カスタムコンポーネントで使用されている親コンポーネントからformGroupを再初期化するときに問題が発生しました。私が得るエラーは:
名前が「selectedCompany」のフォームコントロール要素にアタッチされたFormControlインスタンスはありません
[〜#〜] html [〜#〜]:
<form [formGroup]="addForm">
...
<my-custom-component formControlName="selectedCompany"></my-custom-component>
...
</form
<my-custom-component>
は、カスタムformControlコンポーネントを作成する有効な方法に従って作成されます: https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html# implement-controlvalueaccessor
コンポーネント
これはformGroup変数addForm
を初期化するコードです:
let formTemp: any = {
selectedCompany: new FormControl(null, [Validators.required]),
}
this.addForm = this._formBuilder.group(formTemp);
addForm
が初めて初期化されたときはすべて問題ありません。しかし、フォームが配置されている場所でモーダルを再度開き、同じコンポーネントコードが実行されると、上記のエラーが発生します。
コンポーネントが古いformGroupへの参照を失うため、formGroupを何度も再初期化することは適切ではないことがわかりました。
新しい値を表示するために値を設定する必要がある場合は、.setValue
はここでの解決策です:
コンポーネント
addForm
を再初期化する代わりに、addForm
が以前に初期化されているかどうかを確認し、初期化されている場合は、既存のFormControls
の値のみを設定します。
if (this.addForm) {
this.addForm.setValue({
selectedCountry: null
})
} else {
let formTemp: any = {
selectedCompany: new FormControl(null, [Validators.required]),
}
this.addForm = this._formBuilder.group(formTemp);
}
このようにして、古いaddForm
への参照が失われないようにしたので、エラーは発生しません。
そのための私の解決策は、formControlName
をformControl
で置き換えることです。
の代わりに
<my-custom-component formControlName="selectedCompany"></my-custom-component>
使用する
<my-custom-component [formControl]="addForm.controls['selectedCompany']"></my-custom-component>
または、formControl
を取得するためのいくつかのgetMethod
エラーでも機能します:
パスを持つフォームコントロール要素に接続されたFormControlインスタンスがありません
いくつかのFormArray
を使用しました。
これに対する奇妙な「解決策」を見つけました。そのため、formGroupを使用するサブコンポーネントをリセットし、スワップアウトすると混乱します。私はこのハックを使用しています。
comp.ts
public flicker: boolean = false;
reInit() {
this.flicker = true;
this.addForm = this._formBuilder.group({
selectedCompany: new FormControl(null, [Validators.required]),
});
setTimeout( () => this.flicker = false, 200); //On very heavy pages, timeout ensures that the flicker hack works as expected.
}
comp.html
<form [formGroup]="addForm" *ngIf="!flicker">
...
<my-custom-component formControlName="selectedCompany"></my-custom-component>
...
</form>
恐ろしいハック。基本的にはformGroupコンポーネントを強制的に破壊して再初期化しますが、絶望的な時間には絶望的な対策が必要です...
FormGroupオブジェクトを使用してフォームの結果を結果の中間配列に保存するため、このハックが必要でした。各結果は自由に再オープンして編集できます。将来的には、この問題を回避するために、ngModelベースのフォームの状態を保存する予定ですが、一時的な解決策がここにあります。
setTimeout( () => this.flicker = false, 200); //On very heavy pages, timeout ensures that the flicker hack works as expected.
フリッカーを同期的に行うより良い方法があります
this.flicker = true;
this._changeDetectorRef.detectChanges();
this.flicker = false;
this._changeDetectorRef.detectChanges();
変更を検出すると、同期的に変更検出が実行され、ビューが更新されるため、古いフォームグループが削除されます。