Angular 2:リアクティブフォームコントロールを繰り返します


回答:


198

Object.keysこれを処理できることがわかりました。

    Object.keys(this.form.controls).forEach(key => {
      this.form.get(key).markAsDirty();
    });

Angular 8+の場合、以下を使用します(ミケランジェロの回答に基づく):

    Object.keys(this.form.controls).forEach(key => {
      this.form.controls[key].markAsDirty();
    });

2
onSubmitでこの関数を使用すると、エラーCannot invoke an expression whose type lacks a call signature. Type 'AbstractControl' has no compatible call signatures.が発生します。理由はわかりますか?
maidi 2017

1
Object.keys(this.registerForm.controls).forEach(key => {this.registerForm.controls [key] .markAsDirty();});
Foad 2017

Object.keysまたは「forin」を試しても何も得られません。それでも、console.log(form.controls)を使用すると、オブジェクトに含まれているさまざまなフォームコントロールをすべて確認できます。私は困惑しています。
ジェイクシェイクスワース2017年

Angular 5を使用すると、markAsDirty()/ markAsTouched()はサブFormGroupsに再帰しません。上記のコードを再帰関数に分割し、任意のサブフォームグループで呼び出します。ユーザーが必要な要素に触れない場合に備えて、現在のAngular Material UIプロジェクトを使用すると、より適切に機能します。ユーザーがフォームを送信してその時点でマークを付けようとすると、このプロジェクトを呼び出します。
ロバート

3
私の投稿を読んであなた自身の答えを更新してくれたThnx。公式ドキュメントも古くなっているので、すべての行を印刷してこれを理解する必要がありました...
ミケランジェロ

56

その価値については、Object.keys(...)マジックを使用せずにこれを行う別の方法があります。

for (const field in this.form.controls) { // 'field' is a string

  const control = this.form.get(field); // 'control' is a FormControl  

}

ループのインデックスを取得する方法は?
SVK

1
TSLintを使用している場合、コードは機能しますが、TSLintは「for(... in ...)ステートメントはifステートメント(forin)でフィルター処理する必要があります」と文句を言います。
イェネファー

1
tslintが指摘しているのは、for ... inステートメントstackoverflow.com/questions/40770425/…
EgleKreivyte19年

41

受け入れられた答えはフラットフォーム構造に対して正しいですが、元の質問に完全には答えていません。WebページにはネストされたFormGroupsとFormArraysが必要な場合があり、堅牢なソリューションを作成するには、これを考慮する必要があります。

public markControlsDirty(group: FormGroup | FormArray): void {
    Object.keys(group.controls).forEach((key: string) => {
        const abstractControl = group.controls[key];

        if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) {
            this.markControlsDirty(abstractControl);
        } else {
            abstractControl.markAsDirty();
        }
    });
}

instanceofTypescriptによってトランスパイルされた後は常に機能しますか?
注目すべき

@ the-notableinstanceofはTypeScript固有のキーワードではありません(developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…class。データタイプでもありません。
キーナンディッグス

8

@Marcosの回答を使用して、formGroupをパラメーターとして渡すことで呼び出すことができる関数を作成しました。この関数は、たとえば、サービス内に配置するコードのより多くの場所から使用できるようにするために、すべてのformGroup子コントロールをダーティにマークします。

public touchAllFormFields(formGroup: FormGroup): void {
    Object.keys(formGroup.controls).forEach((key) => {
        formGroup.get(key).markAsDirty();
    });
}

それが役に立てば幸い ;)


完璧!clearValidators、untouchなどと同様の関数とともにサービスに追加されました。ネストされたコントロールの再帰的チェックを追加したい場合がありますが、これは今のところ機能します。ありがとう!
mc01 2018

6

思われるget 機能は、角8でフォーム内の特定の値を取得するためのもう働いていないので、これは私が@Liviuアイリーの回答に基づいて、それを解決する方法です。

for (const field in this.myForm.controls) { // 'field' is a string
  console.log(this.myForm.controls[field].value);
}

本気ですか?APIドキュメントにはすでに抽象制御用のgetメソッドがあります(angular.io/api/forms/AbstractControl#get)。まだ移行していません。今、私は(⊙_◎)怖い
アラン・グロース

@AlanGroszええ、私はそれを書き直しているときにもそれを見ましたが、コンソールのすべての行を印刷しているときでさえ、オブジェクトにgetメソッドを見つけることができませんでした。ドキュメントが遅れていると思います。移行して頑張ってください!
ミケランジェロ

彼らがそれを削除したとは思わない。Angular8
Laszlo Sarvold

5

    Object.keys( this.registerForm.controls).forEach(key => {
       this.registerForm.controls[key].markAsDirty();
    });


4

これは私のために働いているものです

private markFormGroupTouched(formGroup: FormGroup) {
  Object.keys(formGroup.controls).forEach((key) => {
    const control = formGroup.controls[key];
    control.markAsDirty();
    if ((control instanceof FormGroup)) {
      this.markFormGroupTouched(control);
    }
  });
}

1

この関数を作成して作成します*「order」という名前のコントロールがあり、インデックスを彼に渡します。

{"conditionGroups": [
   {
     "order": null,
     "conditions": []
   }
  ]
}


updateFormData() {
    const control = <FormArray>this.form.controls['conditionGroups'];  
    control.value.map((x,index)=>{
    x.order = index; 
 })
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.