【问题标题】:Angular ngFor lifecycleAngular ngFor 生命周期
【发布时间】:2018-11-19 06:23:05
【问题描述】:

我正在使用*ngFor 来迭代一些这样的数据:

<div *ngFor="let d of [1, 2, 3]"> {{d}} </div>

一切都很好,我得到了预期的结果:

<div> 1 </div>
<div> 2 </div>
<div> 3 </div>

然后,想知道是不是用函数代替{{d}},所以写了一个函数:

protected logAndReturn(item) {
    console.log(item);
    return item;
}

我用过:

<div *ngFor="let d of [1, 2, 3]"> {{logAndReturn(d)}} </div>

我得到了与第一个代码相同的渲染 HTML 结果,但控制台输出不是我预期的输出。 控制台输出:

1
2
3
1
2
3

Angular is running in the development mode. Call enableProdMode() to enable the production mode.

1
2
3
1
2
3

添加的函数现在被调用了 12 次(每个项目 4 次)

这是你可以自己测试的代码:jsfiddle

我的代码错了吗?有什么解决方案可以防止这些额外的电话吗?为什么会发生这种情况,谁能解释一下?

【问题讨论】:

    标签: angular ngfor angular-components angular-component-life-cycle


    【解决方案1】:

    此问题与*ngFor 无关,这是插值({{ }}) 内的expression 的正常行为。它被 Angular 多次调用,以检查 expression 是否已更改。插值用于获取(打印)expressions,不建议调用methods。它会不必要地触发。

    Issue is with the method inside interploation not *ngFor

    【讨论】:

      【解决方案2】:

      在视图中使用方法与使用不纯管道相同。这段代码将在视图上的每个事件中执行,可能会执行很多次。在我们的示例中,logAndReturn() 方法仅返回一个数字,因此可以假设在视图中运行它,但如果它会执行更复杂的操作,则可能是一个很大的性能问题。使用一个简单的程序,您可以检查 console.log 以查看“logAndReturn”的跟踪是在哪一步打印的。这是新组件的外观:

      export class AppComponent implements 
      OnChanges,
      OnInit,
      DoCheck,
      AfterContentInit,
      AfterContentChecked,
      AfterViewInit,
      AfterViewChecked,
      OnDestroy
      {
        private var01: string = "default value";
        constructor( private trans: TranslatorService ){}
        ngOnChanges (){
           console.log('Trace OnChanges');
        }
        ngOnInit (){
           console.log('Trace onInit');
        }
        ngDoCheck (){
           console.log('Trace doCheck');
        }
        ngAfterContentInit(){
           console.log('Trace After Content Init');
        }
        ngAfterContentChecked(){
           console.log('Trace after contente checked');
        }
        ngAfterViewInit(){
           console.log('Trace after view init');
        }
        ngAfterViewChecked(){
           console.log('Trace after view checked');
        }
        ngOnDestroy(){
           console.log('Trace on destroy');
        }
        testRender() {
          console.log('trace 01');
          return 'This is a test that runs a console log'
        }
        (...)
      }
      

      要更深入地了解这里真正发生的事情,请阅读 Angular 2 关于life cycle的官方文档

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-22
        • 2018-08-30
        • 2018-05-02
        • 1970-01-01
        • 2018-01-11
        • 2019-06-26
        • 2018-05-28
        相关资源
        最近更新 更多