I need to add the vertical line splitter between the div. But the div which is present at the end of the line should not contain the splitter. The div will be placed dynamically.
https://stackblitz.com/edit/angular-ivy-lxhcuu?file=src/app/app.component.css
document.addEventListener('DOMContentLoaded', () => {
const parent = document.querySelector(".parent");
const node = parent.firstElementChild;
for (let i = 1; i < 30; i ) {
parent.appendChild(node.cloneNode(true));
}
});
p {
font-family: Lato;
}
.parent {
display: flex;
flex-flow: wrap;
}
.paddingDta {
padding: 5px;
}
.divider {
border-left: 1px solid red;
}
.dividerPadding {
margin: 2px;
}
<div >
<div>
<div >
{{ data }}
<span ></span>
</div>
</div>
</div>
CodePudding user response:
Well... This is kinda sophisticated problem, that can be solved in many different ways depending on usecase.
But long story short, I don't know any "tricky" way to fix this issue without "bruteforcing" it with checking position of every element on the list:
// I've used custom directive for this example for easier hook
// But you can use local variables as well
<div [someName]="i"> <-- content --> </div>
// View Children to hook to HTMLElement of our list items
@ViewChildren(FlexBorderDirective) els: QueryList<FlexBorderDirective>;
Then you need to check offset position of every element and check which is further from left side of the screen. I've used function like this, however you might think about better way to check each element:
checkLastElements(_elements: Array<HTMLDivElement>) {
// Clear table for resize
this.lastElementsIndexes = [];
// Not optimal, but good enough for example
for (let i = 0; i < _elements.length; i ) {
if (i 1 < _elements.length)
if (_elements[i].offsetLeft > _elements[i 1].offsetLeft) {
// Push "last element index" to another array for checking
this.lastElementsIndexes.push(i);
}
}
// "Force push" last element to our list
this.lastElementsIndexes.push(_elements.length - 1);
}
We also have to wait for View to init, so we should call this function inside "AfterViewInit" lifecycle hook
ngAfterViewInit() {
// Its just to prevent "checking error", I don't have time to
resolve this :)
setTimeout(() => {
this.checkLastElements(this.els.map((_element) => _element.el));
}, 0);
}
setTimeout is used because Angular was checking variables before they've changed. It wasn't critical bug, however it's the simplest way to resolve this warning/error message in console.
The last "tweak" would be checking "last elements" on window resize event. Angular helps us a lot with this task, and you can simply call our checkLastElements
function in our HostListener
// Handle resize window event
@HostListener('window:resize', ['$event'])
onResize(event) {
this.checkLastElements(this.els.map((_element) => _element.el));
}
full stackblitz example:
https://stackblitz.com/edit/angular-ivy-jskkaf?file=src/app/app.component.ts
However, for example if you have some "static container" like in bootstrap-css .container class, you might want to use css pseudo element :nth-child/:nth-of-type and @media.
CodePudding user response:
You can use let isLast = last in ngFor and send it as a parameter to the component.