Angular2でフォームバリデーターをトリガーする方法


82

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

例:チェックボックスXと入力Pが与えられました。入力Pには、Xのモデル値に基づいて異なる動作をするバリデータがあります。Xがチェック/オフの場合、Pでバリデータを呼び出す必要があります。Pのバリデータはモデルを次のように調べます。 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']);
    }
});

誰かが解決策を持っていますか?ありがとう!


Xの値に基づいて検証を有効/無効にしようとしているだけですか?どのようなバリデーターを使用していますか?スコープ内の条件に基づいてバリデーターを実行させることができますが、そのアプローチが機能するかどうかはわかりません。参照: stackoverflow.com/questions/21370006/...
stephen.vakil

@ stephen.vakil-私はangular2を使用しています。
ボンネビル2015

@Bonnevilleは、チェックボックスの状態をバリデーター関数に渡す方法を説明していただけますか?
Varun Mulloli 2016年

回答:


79

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

これを見てください: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:実際の実装へのリンクを変更し、ドキュメントへのリンクを追加しました

Validaton-ガイド

FormControlドキュメント


提案してくれた@Nightkingに感謝します。試してみます。リンクが機能していないことに注意してください。
ボンネビル

@Bonneville情報をありがとう。彼らはフォームコードを共通の名前空間に抽出しました。物事は少し速くに変わります:)。ソースへのリンクを更新しました。
ナイトキング2015年

私はついにこのコードの使用に取り掛かりました、そしてそれは私のために働いているようです。ありがとう!ところで、コードにタイプミスがあります。updateValueAndValidity()関数に文字「e」がありません。コードが更新ではなく更新されています。乾杯、これは大きな助けになりました!
ボンネビル2015

1
リンクが壊れています。github.com/angular/angular/blob/master/packages/forms/src/…に更新される可能性がありますが、まったく同じではありません。Angularドキュメントにリンクすることもできます
Explosion Pills 2017

1
命の恩人!私が立ち往生したユースケースは、ユーザーが単一のフォームコントロールに触れずにフォームを送信したときでした。フォームは無効であるが、任意のエラーメッセージが表示されないコントロール
pravin

42

私のControlGroupでこれを行うのは、タッチされているかどうかをチェックするエラーdivがあるためです。

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

(this.formは私のControlGroupです)


これは実際には正しい答えです。単一入力が必要な場合this.form.controls ['name']。markAsTouched();
chris_r

19

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

ブログリンク

私はナイトキングの答えを組み合わせた解決策に出くわしました

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

});

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



6

この動作をモデル化するより洗練された方法があります-たとえば、状態をReplaySubjectに入れてそれを監視し、次に状態を監視する非同期バリデーターを使用します-しかし、以下の疑似コード化されたアプローチは機能するはずです。チェックボックスの値の変化を観察し、必要に応じてモデルを更新してから、updateValueAndValiditycalを使用して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
  });
}

0
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);
        }
    };
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.