簡體   English   中英

Angular2子組件在ngFor中意外銷毀

[英]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的有關登錄評論ngOnDestroySomeComponent我發現,它是在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM