web-dev-qa-db-ja.com

フォームコントロールのvalueChangesは前の値を提供します

フォームオブジェクトparentForm内に'question1'という名前のフォームコントロールがあり、次の方法でサブスクライブしました。

YesNoの2つのオプションを持つラジオボタン。Noを選択するとYesが表示され、Yesを選択するとNoになります。

this.parentForm.controls['question1'].valueChanges.subscribe(
  (selectedValue) => {
    // If option `No is selected`
    console.log(selectedValue);  // displays No. OK
    console.log(this.parentForm.value['question1']);  // displays Yes. Problem is here
  }
);

selectedValue変数の値は正しいですが、console.log(this.parentForm.value['question1']を実行すると、以前の値が返されます。

this.parentForm.value['question1']から値を取得する前にsetTimeout()を追加しようとしましたが、正常に動作します。

setTimeout(() => {
  console.log(this.parentForm.value['question1']); // gives the correct value.
}, 500);

しかし、私の質問は、そのコントロールの値が変更されたときにparentFormが更新されない理由であり、それも値が変更された後にのみその値を取得しています。

注:私の要件ではなく、parentForm.valueChangesを監視したくありません。

25
Amit Chigadani

valueChangesはObservableであるため、pairwiseをパイプして、サブスクリプションの前の値と次の値を取得できます。

// No initial value. Will emit only after second character entered
this.form.get('fieldName')
  .valueChanges
  .pipe(pairwise())
  .subscribe(([prev, next]: [any, any]) => ... );
// Fill buffer with initial value, and it will emit immediately on value change
this.form.get('fieldName')
  .valueChanges
  .pipe(startWith(null), pairwise())
  .subscribe(([prev, next]: [any, any]) => ... );

StackBlitzで動作する例: https://stackblitz.com/edit/angular-reactive-forms-vhtxua

32
mtpultz

valueChangesイベントが発生しますafter新しい値はFormControl値に更新され、before変更はその親と先祖にバブルアップされます。したがって、FormControl値オブジェクト(イベント中に変更されない)のフィールドではなく、FormGroup自体(パッチを適用したばかり)の値にアクセスする必要があります。

それを踏まえて、代わりにthis.parentForm.get('question1').valueを使用してください:

this.parentForm.controls['question1'].valueChanges.subscribe(
    (selectedValue) => {
      console.log(selectedValue);
      console.log(this.parentForm.get('question1').value);     
    }
);
26
Harry Ninh

もう1つのオプションがありますが、すべての場合に適しているわけではありません。FormControlでselectedValueが更新される前にone tickを待つことができます。

setTimeout( () => console.log( selectedValue ) );

同期/非同期フォームトピックの詳細: リアクティブフォーム Angularガイドドキュメント。

3
nesinervink

これを試してください

this.parentForm.controls['question1'].valueChanges.subscribe(
    (selectedValue) => {
      console.log(selectedValue);
      console.log(this.parentForm.value.question1);     
    }
);

formBuilderのコントロールが更新された場合、プロパティ値を介してFormBuilderオブジェクトから最後の値をすぐに回復できます。