web-dev-qa-db-ja.com

複数のコンポーネント間でFormGroupを渡す

angular 2+アプリケーションでリアクティブフォームを使用しています。ヘッダー、フッターなど、フォームのさまざまな部分を個別に管理できるように、メインのFormGroupを複数のコンポーネントに渡す必要があります。コンポーネントとそれらの異なるコンポーネントによって入力されます。これは、現時点で私がそれを行っている方法です:

<div class="container-fluid">
  <form [formGroup]="orderForm">
    <order-header [orderForm]="orderForm"></order-header>
    <order-items [orderForm]="orderForm"></order-items>
    <order-footer [orderForm]="orderForm"></order-footer>
  </form>
</div>

これが正しいアプローチであるかどうか疑問に思っていますが、このコードで警告/エラーが表示されます:

エラーエラー:ExpressionChangedAfterItHasBeenCheckedError:チェック後に式が変更されました。以前の値: 'true'。現在の値: 'false'。

この行で:

<form [formGroup]="orderForm">

助言がありますか?ありがとう。

9
adeelmahmood

Juliaが述べたように、これは正常な動作です。

これを引き起こしているのは、実際にはコンポーネントの@Inputであり、行<form [formGroup]="orderForm">ではありません。

これは、開発モード中に発生します。この問題を回避する方法は、orderFormを受け取るコンポーネントで変更検出を手動でトリガーすることです。 @Inputを使用しているため、他のコンポーネントでngOnChangesライフサイクルフックを使用できます。

import { ChangeDetectorRef } from '@angular/core';

@Input() orderForm: FormGroup

constructor(private ref: ChangeDetectorRef) { }

ngOnChanges() {
  this.ref.detectChanges()
}

エラーについて詳しくは、こちらを確認してください: 式___はチェック後に変更されました

また、補足として、フォーム全体を他のコンポーネントに渡す必要が本当にありますか。通常、コンポーネントが処理するネストされたグループのみを渡すため、次のようになります。

<form [formGroup]="orderForm">
  <order-header [orderForm]="orderForm.controls.myNestedGroupName"></order-header>
</form>

補足として! :)

11
AJT82

あなたはそれを正しくやっています。 Angular devモードで2つの変更検出サイクルを実行します。1つは正常で、2つ目は、呼び出されたすべての関数が1回目と2回目で同じ結果を返すことを確認します。すべての@Inputまたは関数を確認します。値をレンダリングするためにテンプレートから呼び出されても、値は変更されません。

たとえば、long()関数は常に異なる値を返すため、このコンポーネントはこの例外をスローします。

@Component({
  selector: 'my-app',
  template: `
      {{long()}}
  `,
})
export class App {
  name:string;
  i=0;

  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }

  long(){
    return this.i++;
  }
}
1