Угловой нг для жизненного цикла
Я использую *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
Мой код неверен? Есть ли решение, чтобы предотвратить эти дополнительные звонки? Почему это произошло и кто-нибудь может объяснить это немного?
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 о жизненном цикле.
Эта проблема не имеет отношения к *ngFor
Это нормальное поведение expression
внутри интерполяции ({{ }})
, Он вызывается угловым преднамеренно несколько раз, чтобы проверить, expression
изменился Интерполяция предназначена для извлечения (печати) expressions
и не рекомендуется для вызова methods
, Это будет стрелять без необходимости.