web-dev-qa-db-ja.com

Angular-バリデータを動的に追加/削除する

私は以下のように定義されたFormGroupを持っています:

this.businessFormGroup: this.fb.group({
    'businessType': ['', Validators.required],
    'description': ['', Validators.compose([Validators.required, Validators.maxLength(200)])],
    'income': ['']
  })

businessTypeOtherの場合、descriptionからValidators.requiredバリデーターを削除します。 businessTypeOtherでない場合、Validators.requiredを追加し直します。

次のコードを使用して、Validators.requiredを動的に追加/削除します。ただし、既存のValidators.maxLength検証をクリアします。

if(this.businessFormGroup.get('businessType').value !== 'Other'){
    this.businessFormGroup.get('description').validator = <any>Validators.compose([Validators.required]);               
} else {                
    this.businessFormGroup.get('description').clearValidators();               
}

this.businessFormGroup.get('description').updateValueAndValidity(); 

私の質問は、requiredバリデーターを追加/削除するときに既存のバリデーターをどのように保持するかです。

13
A J Qarshi

角度のあるフォームには、バリデータのプログラムによる割り当てを可能にする組み込み関数 setValidators() があります。

あなたの例では次のことができます:

if(this.businessFormGroup.get('businessType').value !== 'Other'){
    this.businessFormGroup.controls['description'].setValidators([Validators.required, Validators.maxLength(200)]);              
} else {                
    this.businessFormGroup.controls['description'].setValidators([Validators.maxLength(200)]);               
}

この方法を使用すると、既存のバリデーターが上書きされるため、必要な/必要なすべてのバリデーターを含める必要があることに注意してくださいリセットするコントロール。

20
Narm

これは私のために働く

   onAddValidationClick(){
         this.formGroup.controls["firstName"].setValidators(Validators.required);
        this.formGroup.controls["firstName"].updateValueAndValidity();
      }

onRemoveValidationClick(){
         this.formGroup.controls["firstName"].clearValidators();
        this.formGroup.controls["firstName"].updateValueAndValidity();
      }
4
San Jaisy

単純なアプローチは、条件変数が変更されるたびにコントロールのバリデーターを設定することです。しかし、実際には、インダイレクション+関数型プログラミングを使用することで、それよりもうまくやることができます。

ブーランフラグとして機能するdescriptionIsRequiredゲッターの存在を考慮してください。

アイデア:

  • descriptionIsRequiredを引数として受け取り、それに応じて必要な+ maxLengthまたはmaxLengthに対してコントロールを検証するカスタムバリデーター関数を作成します。
  • コントロールの有効性が評価されるときに、descriptionIsRequiredの最新の値が考慮されるように、カスタムバリデーターを説明コントロールにバインドします。

最初のポイントは、実装するのが非常に簡単です。

function descriptionValidator(required: boolean): ValidatorFn {
  return (formControl: FormControl): ValidationErrors => {
    if (required) {
      return Validators.compose([Validators.required, Validators.maxLength(200)])(formControl);
    } else {
      return Validators.maxLength(200)(formControl);
    }
  }
}

これは自己カプセル化関数であることに注意してください。

2番目のポイントはもう少し複雑ですが、最終的には次のようになります。

export class FooComponent {
  constructor(){
    this.form = fb.group({
      description: ['initial name', this.validator()]
    });
  }

  private get descriptionIsRequired(): boolean {
   ...
  }

  private validator(): ValidatorFn {
    return (c: FormControl): ValidationErrors => descriptionValidator(this.descriptionIsRequired)(c);
  }
}

何が起こっているかの簡単な説明:

  • validatorメソッドは関数を返します
  • validatorによって返される関数は、factory methodと考えることができます:呼び出されるたびに、新しい関数、より具体的には新しいインスタンスを返しますdescriptionValidatorの最新のdescriptionIsRequired値を使用します。

次のライブデモ stackblitz

3
Jota.Toledo

たぶんこれは役立ちます:

Validators.requiredを既存のAbstractControlのvalidatorsetに追加します。

if (c.validator !== null) {
        c.setValidators([c.validator, Validators.required])
  } else {
        c.setValidators([Validators.required])
  }
2
Rob