我还没有深入研究ngFor如何在幕后呈现元素。但是从观察中,我注意到它通常倾向于每个正在迭代的项计算多次表达式。
这会导致在检查ngFor“last”变量时进行任何typescript方法调用时,有时会触发多次。
为了保证ngFor在正确完成对项的迭代时仅调用一次您的typescript方法,您需要针对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;
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' 没有括号 '()',因为我们只是传递了一个对 TypeScript 方法的引用,而不是在此处实际调用它。
最后,这是你的 TypeScript 文件中 'doSomething' 方法的样子:
public doSomething=()=> {
console.log("triggered from the directive's parent component when ngFor finishes iterating");
}