[英]Angular2 Child component destroyed unexpectedly in ngFor
所以我有一個帶有@Output
事件的from的Component,它在提交時觸發,如下所示:
@Component({
selector: 'some-component',
templateUrl: './SomeComponent.html'
})
export class SomeComponent{
@Input() data: any;
@Output() onSubmit: EventEmitter<void> = new EventEmitter<void>();
constructor(private someService: SomeService) {}
submitForm(): void{
this.someService.updateBackend(this.data, ()=>{
this.onSubmit.emit();
});
}
}
我正在使用ngFor
來創建此Component的多個元素:
<template let-data ngFor [ngForOf]="dataCollection">
<some-component [data]="data" (onSubmit)="doSomthing()"></some-component>
</template>
最后一個缺失的部分是提交時使用的服務:
@Injectable()
export class SomeService{
constructor() {}
updateBackend(data: any, callback: () => void): void{
/*
* updating the backend
*/.then((result) => {
const { errors, data } = result;
if (data) {
callback();
}
})
}
}
在submitForm()
函數的開頭, this.onSubmit.observers
是一個包含一個觀察者的數組,就像它應該的那樣。
一旦它到達調用this.onSubmit.emit()
的回調方法, this.onSubmit.observers
就是一個包含ZERO觀察者的數組。
SomeService.updateBackend
的后端它完全正常, observers
仍然是一個包含一個觀察者的數組! ngFor
並且只顯示一個<some-element>
它也可以正常工作,將一個觀察者this.onSubmit.observers
在回調范圍內的this.onSubmit.observers
中! 知道我做錯了什么嗎?
提前致謝!
感謝@ StevenLuke的有關登錄評論ngOnDestroy
的SomeComponent
我發現,它是在EMIT之前銷毀。
實際上,當SomeService.updateBackend
完成時,它正在做的第一件事是銷毀該組件的所有實例並重新創建它們!
這就是觀察者改變的原因! 為什么會這樣?
如果在* ngFor中提供trackBy函數來標識dataCollection中的項,則不會銷毀和初始化。 你的模板是:
<some-component *ngFor="let data of dataCollection;trackBy:trackByFunction"
[data]="data" (onSubmit)="doSomthing()"></some-component>
trackByFunction看起來像:
trackByFunction(index, item) {
return item ? item.id : undefined;
}
因此,即使dataCollection中的項是新對象,如果其id與前一個集合中的id匹配,* ngFor將更新[data]但不會銷毀並初始化該組件。
感謝@GünterZöchbauer評論我發現情況是ngFor
綁定的數據被更新后端的新實例替換,因此,它重新渲染了它的子組件導致它們重新初始化(destory + init),使Component的實例被覆蓋。
為了解決這個問題,我必須將dataCollection
放在一個單獨的服務中,為父組件ngOnInit
獲取它,保存它不會導致重新ngFor
,並且只有在子組件執行結束后再次獲取它的數據
希望它對某人有幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.