6

@Outputしたがって、次のように、送信時にトリガーされるイベントを持つ from のこのコンポーネントがあります。

@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は、本来あるべき 1 つのオブザーバーを含む配列です。

this.onSubmit.emit()が呼び出されるコールバック メソッドに到達するとすぐに、this.onSubmit.observersはゼロのオブザーバーを含む配列になります。

2 つの非常に奇妙な動作が発生しています。

  • バックエンドを更新する実際の呼び出しを削除するSomeService.updateBackendと、完全に正常に動作し、observersまだ 1 つのオブザーバーを含む配列です!
  • バックエンドへの実際の呼び出しを保持するが、使用せずにngFor1 つだけを表示する<some-element>場合も、完全に正常に動作し、1 つのオブザーバーをthis.onSubmit.observersコールバック スコープ内に保持します!

私は何が間違っているのですか?

前もって感謝します!

アップデート:

のログ記録に関する @StevenLuke のコメントのおかげで、出力前に破棄されていることngOnDestroySomeComponentわかりました。

実際、終了時に最初に行うことはSomeService.updateBackend、このコンポーネントのすべてのインスタンスを破棄して再作成することです!

これがオブザーバーを変えるものです!なぜそれが起こるのでしょうか?

4

2 に答える 2

2

@GünterZöchbauer のコメントのおかげでngFor、バックエンドを更新したときに、バインドされているデータが新しいインスタンスに置き換えられていたため、再レンダリングされた子コンポーネントであることがわかりました。上書きされる Component のインスタンス。

この問題を解決するためにdataCollection、 を別のサービスに配置し、親コンポーネント用に取得し、 の再ngOnInitレンダリングを引き起こさないように保存しngFor、子コンポーネントの実行が終了した後にのみデータを再度フェッチする必要がありました

誰かの役に立てば幸いです!

于 2016-09-14T16:35:41.353 に答える