我还没有深入研究 ngFor 如何在后台渲染元素。但从观察来看,我注意到它通常倾向于对每个迭代的项目多次评估表达式。
这会导致在检查 ngFor 'last' 变量时进行的任何打字稿方法调用有时会被触发多次。
为了保证 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;
// 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' 在这里没有方括号 '()',因为我们只是传递了对 typescript 方法的引用,而实际上并没有在这里调用它。
最后是你的打字稿文件中“doSomething”方法的样子:
public doSomething=()=> {
console.log("triggered from the directive's parent component when ngFor finishes iterating");
}