web-dev-qa-db-ja.com

Angular2でフォームバリデータをトリガーする方法を知っている人はいますか?

Angular2では、別のコントロールが変更されたときにいくつかのコントロールのバリデーターをトリガーしたいです。フォームに再検証を指示する方法はありますか?さらに良いことに、特定のフィールドの検証を要求できますか?

例:与えられたチェックボックスXと入力P。入力Pには、Xのモデル値に基づいて異なる動作をするバリデーターがあります。 Xの状態を判別し、それに応じてPを検証します。

コードは次のとおりです。

constructor(builder: FormBuilder) {
    this.formData = { num: '', checkbox: false };

    this.formGp = builder.group({
        numberFld: [this.formData.num, myValidators.numericRange],
        checkboxFld: [this.formData.checkbox],
    });
}

this.formGp.controls['checkboxFld'].valueChanges.observer({
    next: (value) => {
        // I want to be able to do something like the following line:
        this.formGp.controls['numberFld'].validator(this.formGp.controls['numberFld']);
    }
});

誰にも解決策がありますか?ありがとう!

62
Bonneville

あなたがまだ答えを探しているかどうかわかりませんので、ここに私の提案があります:

これを見てください: Angular 2-AbstractControl

あなたができることは次のことだと思います:

this.formGp.controls['checkboxFld'].valueChanges.observer({
    next: (value) => {
       this.formGp.controls['numberFld'].updateValueAndValidity();
    }
});

これにより、バリデーターがトリガーおよび実行されます。さらに、状態も更新されます。これで、バリデータロジック内のチェックボックス値を参照できるようになります。

お役に立てれば!

編集:リンクと例を更新しました。答えを書いている間にコードが変更されました。

EDIT_2:alpha.48はEventEmitter.observerをEventEmitter.subscribeに変更します!

EDIT_3:実際の実装へのリンクを変更し、ドキュメントへのリンクを追加しました

バリダトンガイド

FormControlドキュメント

62
Nightking

私のControlGroupでは、タッチするとエラーdivがチェックされるため、これを行います

for (var i in this.form.controls) {
  this.form.controls[i].markAsTouched();
}

(this.formは私のControlGroupです)

30
kernowcode

このブログの助けを借りて

ブログリンク

Nightkingの回答を組み合わせて解決策を見つけました

Object.keys(this.orderForm.controls).forEach(field => {
       const control = this.orderForm.get(field);
       control.updateValueAndValidity();

});

this.orderFormはフォームグループです

7
Altair CA

この動作をモデル化するよりエレガントな方法があります-たとえば、状態をReplaySubjectに入れてそれを観察し、次に状態を観察する非同期バリデーターを使用します-しかし、以下の擬似コード化されたアプローチは機能します。チェックボックスで値の変更を確認し、必要に応じてモデルを更新してから、updateValueAndValidity calでnumberFldの再検証を強制します。

constructor(builder: FormBuilder) {
  this.formData = { num: '', checkbox: false };
  const numberFld = builder.control(this.formData.num, myValidators.numericRange);

  const checkbox = builder.control(this.formData.checkbox);
  checkbox.valueChanges.map(mapToBoolean).subscribe((bool) => {
    this.formData.checked = bool;
    numberFld.updateValueAndValidity(); //triggers numberFld validation
  });

  this.formGp = builder.group({
      numberFld: numberFld,
      checkboxFld: checkbox
  });
}
5
jmreidy
static minMaxRange(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        if (Validators.min(min)(control)) { // if min not valid
            return Validators.min(min)(control);
        } else {
            return Validators.max(max)(control);
        }
    };
}
0
pogiaron