Angular ngFor lifecycle

泪湿孤枕 提交于 2019-12-20 03:17:00

问题


I'm using *ngFor to iterate some data like this:

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

Everything is fine and I got the result as expected:

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

Then, I wondered if I use a function instead of {{d}}, so I wrote a function:

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

and I used it:

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

I got the same rendered HTML result as the first code, but console output wasn't my expected output. Console output:

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

The added function was called 12 times now (4 time for each item)

Here is the code that you can test it yourself: jsfiddle

Is my code wrong? Is there any solution to prevent these extra calls? Why did this happen and can anybody explain it a little?


回答1:


using methods in the view is the same that using impure pipes. This code will be executed in each event on the view, which can be a lot of times. In our example, the logAndReturn() method only returns a number so it can be assumable to run it in a view but if it would do something more complex, it could be a big problem of performance. with a simple program you can check console.log to see in which step the trace of “logAndReturn” is printed. This is the look of the new component:

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'
  }
  (...)
}

To go deeper in what really is happening here, read the official documentation of Angular 2 about the life cycle




回答2:


This issue has no relation with *ngFor, It's the normal behavior of the expression inside the interpolation ({{ }}). It is called by angular intentionally multiple times to check if the expression has changed. Interpolation is meant for fetching (printing) expressions and not recomended for calling methods. It will fire unnecessarily.

Issue is with the method inside interploation not *ngFor



来源:https://stackoverflow.com/questions/50773368/angular-ngfor-lifecycle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!