Я еще не изучал подробно, как ngFor визуализирует элементы под капотом. Но по наблюдениям я заметил, что он часто имеет тенденцию оценивать выражения более одного раза для каждого элемента, который он повторяет.
Это приводит к тому, что любой вызов метода машинописного текста, сделанный при проверке переменной ngFor 'last', иногда запускается более одного раза.
Чтобы гарантировать один вызов вашего метода машинописного текста с помощью ngFor, когда он правильно завершит итерацию по элементам, вам необходимо добавить небольшую защиту от многократной переоценки выражений, которую ngFor выполняет под капотом.
Вот один из способов сделать это (с помощью директивы), надеюсь, это поможет:
Код директивы
import { Directive, OnDestroy, Input, AfterViewInit } from '@angular/core';
@Directive({
selector: '[callback]'
})
export class CallbackDirective implements AfterViewInit, OnDestroy {
is_init:boolean = false;
called:boolean = false;
@Input('callback') callback:()=>any;
constructor() { }
ngAfterViewInit():void{
this.is_init = true;
}
ngOnDestroy():void {
this.is_init = false;
this.called = false;
}
@Input('callback-condition')
set condition(value: any) {
if (value==false || this.called) return;
// in case callback-condition is set prior ngAfterViewInit is called
if (!this.is_init) {
setTimeout(()=>this.condition = value, 50);
return;
}
if (this.callback) {
this.callback();
this.called = true;
}
else console.error("callback is null");
}
}
После объявления указанной выше директивы в вашем модуле (если вы знаете, как это сделать, если нет, спросите, и я, надеюсь, обновлю это с помощью фрагмента кода), вот как использовать директиву с ngFor:
<li *ngFor="let item of some_list;let last = last;" [callback]="doSomething" [callback-condition]="last">{{item}}</li>
'doSomething' - это имя метода в вашем файле TypeScript, который вы хотите вызвать, когда ngFor завершает итерацию по элементам.
Примечание. «doSomething» не имеет здесь скобок «()», поскольку мы просто передаем ссылку на метод машинописного текста, а не вызываем его здесь.
И, наконец, вот как выглядит метод doSomething в вашем машинописном файле:
public doSomething=()=> {
console.log("triggered from the directive's parent component when ngFor finishes iterating");
}
person
H7O
schedule
24.06.2017