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);
});
}
you can use the AfterViewInit life-cycle hook.
this life-cycle hook is trigger after the view is initialized.
you can use it in this way:
import { AfterViewInit } from '@angular/core';
export class AppComponent implements AfterViewInit{
@ViewChild('ul') ulRef: ElementRef;
ngAfterViewInit() {
// your logic
}
events: any[];
showEvents(): void {
this.events = [
new Date(2017, 1),
new Date(2017, 3),
new Date(2019, 6)
];
const li = this.ulRef.nativeElement.children;
// This logs empty arrays since DOM not changed yet
console.log( li );
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With