I want to animate <li> elements (e.g. usign jQuery).
But how can I detect when DOM is done after *ngFor?
View
<ul #ul>
<li *ngFor="let event of events">{{event|date:'medium'}}</li>
</ul>
<button (click)="showEvents()">Show events</button>
Component
export class AppComponent {
@ViewChild('ul') ulRef: ElementRef;
events: any[];
showEvents(): void {
// Assume this set of events will be different in every button click
this.events = [
new Date(2017, 1),
new Date(2017, 3),
new Date(2019, 6)
];
const li = this.ulRef.nativeElement.children;
// This logs empty array for first time or
// previous set of children for next times
console.log( li );
};
}
P.S. I know using setTimeout will solve this, but is it right approach?
SOLUTION
Thanks to @ThinkingMedia. Using template variable on the <li> and QueryList I can watch for changes.
<ul>
<li *ngFor="let event of events" #li>{{event|date:'medium'}}</li>
</ul>
@ViewChildren('li') li: QueryList<ElementRef>;
ngAfterViewInit(): void {
this.li.changes.subscribe(() => {
const elements = this.li.toArray().map(i => i.nativeElement);
// Here I can have access to the li elements when DOM updated
console.log(elements);
});
}