在ngFor之后如何检测DOM何时准备好?

时间:2017-08-11 11:03:25

标签: angular

我想为<li>元素设置动画(例如,使用jQuery)。

但是如何在 * ngFor 之后检测DOM何时完成?

视图

<ul #ul>
  <li *ngFor="let event of events">{{event|date:'medium'}}</li>
</ul>

<button (click)="showEvents()">Show events</button>

组件

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。我知道使用setTimeout会解决这个问题,但这是正确的做法吗?

感谢@ThinkingMedia。使用<li>QueryList上的模板变量,我可以观察更改。

<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);
    });
  }

1 个答案:

答案 0 :(得分:6)

您可以使用 AfterViewInit 生命周期挂钩。

在视图初始化后触发此生命周期挂钩。

你可以这样使用它:

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 );
  };

}