FormBuilderコントロールの値を手動で設定


174

これは私を混乱させています、私は銃の下にあり、これに丸一日を費やす余裕はありません。

コンポーネント内でコントロール値(「dept」)を手動で設定しようとしていますが、それが機能していません。新しい値でも適切にコンソールに記録されます。

次に、FormBuilderインスタンスを示します。

initForm() {
  this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required],
  });
}

これは、選択したdeptを受け取るイベントハンドラです。

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // This is how I am trying to set the value
  this.form.controls['dept'].value = selected.id;
}

フォームが送信されてログアウトしてもthis.form、フィールドは空白のままです!他のpplの使用を見たことupdateValue()がありますが、これはbeta.1であり、それをコントロールで呼び出す有効なメソッドとは見なしません。

私もupdateValueAndValidity()成功しないで呼び出してみました:(。

ngControl="dept"フォームの残りの部分と同じように、フォーム要素で使用しますが、カスタムディレクティブ/コンポーネントです。

<ng-select
  [data]="dept"
  [multiple]="false"
  [items]="depts"
  (selected)="deptSelected($event)" <!-- This is how the value gets to me -->
  [placeholder]="'No Dept Selected'"></ng-select>

私は同様の状況に遭遇しました、シナリオは値がhttp.get-subscribeに設定されてフォーム値をロードするが、値行を設定すると最初に実行され、サブスクライブは実際には非同期として後で実行されます。したがって、サブスクライブで値を設定する場合は、そのセットを確認してください。my2cents!
HydTechie 2017年

回答:


324

更新日:2017年3月19日

this.form.controls['dept'].setValue(selected.id);

古い:

今のところ、型キャストを実行する必要があります。

(<Control>this.form.controls['dept']).updateValue(selected.id)

あまりエレガントではない。これが将来のバージョンで改善されることを願っています。


6
これはうまくいきます、ありがとう。また、検証をクリアする必要があります: (<Control>this.form.controls['dept']).setErrors(null)
ヘイニーと呼ばれた男

17
まだthis.form.get('dept').setValue(selected.id):)
developer033

6
ただのメモ。インデクサーなしでプロパティに直接アクセスすることもできます。this.form.controls.dept.setValue(selected.id);
James Poulose

しかし、これは新しいデータの検証を実行しません!! 更新後に手動で変更検出をトリガーするにはどうすればよいですか?
ksh

1
それは私のためにこの作品を2019年だ:this.form.controls['dept'].setValue(selected.id);
ジョン・ロペス

98

Angular 2 Final(RC5 +)には、フォームの値を更新するための新しいAPIがあります。patchValue()APIメソッドは、我々は唯一のフィールドの一部を指定する必要が部分的にフォームの更新をサポートしています。

this.form.patchValue({id: selected.id})

setValue()すべてのフォームフィールドを持つオブジェクトを必要とするAPIメソッドもあります。欠落しているフィールドがあると、エラーが発生します。


7
これを追加するために、現在updateValue(Filocheによる承認済みの回答から)は非推奨になっていますsetValue
superjos

2
ここで公式のプルリクエスト Githubの上や廃止の根拠updateValue()と導入patchValueとはsetValue
TheBrockEllis 2016

しかし、これは新しいデータの検証を実行しません!! 更新後に手動で変更検出をトリガーする方法
ksh

16

Aangular 2 finalはAPIを更新しました。彼らはこれのために多くの方法を追加しました。

コントローラーからフォームコントロールを更新するには、次の操作を行います。

this.form.controls['dept'].setValue(selected.id);

this.form.controls['dept'].patchValue(selected.id);

エラーをリセットする必要はありません

参考文献

https://angular.io/docs/ts/latest/api/forms/index/FormControl-class.html

https://toddmotto.com/angular-2-form-controls-patch-value-set-value


2つの違い-でsetValue()呼び出された場合formGroup/formBuilder、フォームの下のすべての値を設定する必要があります。patchValue()を呼び出すと、特定の値を更新するために使用できます。
Vibhor Dube

11

次のメソッドを使用して、リアクティブフォームコントロールの値を更新できます。次の方法のいずれかがニーズに適しています。

setValue()を使用するメソッド

this.form.get("dept").setValue(selected.id);
this.form.controls["dept"].setValue(selected.id);

patchValue()を使用するメソッド

this.form.get("dept").patchValue(selected.id);
this.form.controls['dept'].patchValue(selected.id);
this.form.patchValue({"dept": selected.id});

最後のメソッドは、フォーム内のすべてのコントロールをループするため、単一のコントロールを更新する場合は好ましくありません

イベントハンドラ内で任意のメソッドを使用できます

deptSelected(selected: { id: string; text: string }) {
     // any of the above method can be added here
}

必要に応じて、フォームグループ内の複数のコントロールを更新できます。

this.form.patchValue({"dept": selected.id, "description":"description value"});

9

あなたはこれを試すことができます:

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // This is how I am trying to set the value
  this.form.controls['dept'].updateValue(selected.id);
}

詳細については、updateValueメソッドの2番目のパラメーターに関する対応するJS文書(https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model)をご覧ください。 ts#L269


返信ありがとうございます。ただし、angular2 beta.1ではupdateValueは有効なメソッドではないようです。そのメソッドを使用できるのはどのバージョンですか。
マシューブラウン

1
Typescriptは次のエラーを出します:error TS2339: Property 'updateValue' does not exist on type 'AbstractControl'。そのコンポーネントでは、フォームのタイプはControlGroupです。多分これを使って個別に作成すればうまくいくnew Control()でしょう
マシュー・ブラウン

5

これらのどれも私にとってはうまくいきませんでした。私がしなければなりませんでした:

  this.myForm.get('myVal').setValue(val);

同じことが私にも起こりました。これはなぜですか?
Rehmanali Momin

3
  let cloneObj = Object.assign({}, this.form.getRawValue(), someClass);
  this.form.complexForm.patchValue(cloneObj);

各フィールドを手動で設定したくない場合。


2

@FilocheのAngular 2更新されたソリューション。使用するFormControl

(<Control>this.form.controls['dept']).updateValue(selected.id)

import { FormControl } from '@angular/forms';

(<FormControl>this.form.controls['dept']).setValue(selected.id));

または、@ AngularUniversityのソリューションを使用できます。patchValue


1

私は答えがすでに出ていることを知っていますが、他の新しい参入者が明確なアイデアを得ることができるようにフォームの値を更新する方法について少し簡単に答えたいと思います。

フォーム構造は、例として使用するのに最適です。だから、私の答えを通して、私はそれをフォームとして表します。

this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required]
  });

したがって、フォームは3つのFormControlを持つFormGroupタイプのオブジェクトです。

モデル値を更新するには2つの方法があります。

  • 個々のコントロールに新しい値を設定するには、setValue()メソッドを使用します。setValue()メソッドはフォームグループの構造に厳密に準拠し、コントロールの値全体を置き換えます。

  • patchValue()メソッドを使用して、フォームモデルで変更された、オブジェクトで定義されたプロパティを置き換えます。

setValue()メソッドを厳密にチェックすると、複雑な形式のネストエラーをキャッチできます。一方、patchValue()は、これらのエラーでサイレントに失敗します。

Angularの公式ドキュメントは こちらから

そのため、複数のコントロールを含むフォームグループインスタンスの値を更新する場合、モデルの一部のみを更新することができます。patchValue()は、探しているものです。

例を見てみましょう。patchValue()を使用する場合

this.form.patchValue({
    dept: 1 
});
//here we are just updating only dept field and it will work.

ただし、setValue()を使用する場合は、フォームグループの構造に厳密に従うため、モデル全体を更新する必要があります。だから、書けば

this.form.setValue({
    dept: 1 
});
// it will throw error.

フォームグループモデルのすべてのプロパティを渡す必要があります。このような

this.form.setValue({
      name: 'Mr. Bean'
      dept: 1,
      description: 'spome description'
  });

しかし、私はこのスタイルを頻繁に使用しません。私は、コードをよりクリーンで理解しやすくするために役立つ次のアプローチを使用することを好みます。

私が行うことは、すべてのコントロールを個別の変数として宣言し、setValue()を使用してその特定のコントロールを更新することです。

上記のフォームでは、次のようにします。

get companyIdentifier(): FormControl {
    return this.form.get('name') as FormControl;
}

get dept(): FormControl {
    return this.form.get('dept') as FormControl;
}

get description(): FormControl {
    return this.form.get('description') as FormControl;
}

フォームコントロールを更新する必要がある場合は、そのプロパティを使用して更新します。この例では、ユーザーがドロップダウンリストから項目を選択すると、質問者がdeptフォームコントロールを更新しようとしました。

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // instead of using this.form.controls['dept'].setValue(selected.id), I prefer the following.

  this.dept.setValue(selected.id); // this.dept is the property that returns the 'dept' FormControl of the form.
}

FormGroupのすべてのプロパティとメソッドの方法を知るために、FormGroup APIを見てみることをお勧めします。

追加ゲッターについて知るにはここを参照してください


1

フォームコントロールを使用している場合、これを行う最も簡単な方法は次のとおりです。

this.FormName.get('ControlName').setValue(value);

-1

ヒント:フォームですべてのプロパティを使用しているsetValueが提供していない場合、エラーが発生します。

Must supply a value for form control with name: 'stateOrProvince'.

そのためpatchValue、を使いたくなるかもしれませんが、フォーム全体を更新しようとすると危険な場合があります。私は持ってaddressいないかもしれないstateOrProvinceまたは持っているstateCd、それが米国や世界的であるかどうかに依存して。

代わりに、次のように更新できます-デフォルトとしてnullを使用します。

this.form.setValue( { stateOrProvince: null, stateCd: null, ...address } );
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.