web-dev-qa-db-ja.com

Angular 4-動的パラメーター値を持つカスタムバリデーター

日付が特定の最小日付を超えているかどうかをチェックするカスタムバリデーターを作成しました。

コードは次のようになります。

_export function validateMinDate(min: Date): ValidatorFn {
    return (c: AbstractControl) => {

        if (c == null || c.value == null)
            return null;

        let isValid = c.value >= min;
        if (isValid) {
            return null;
        } else {
            return {
                validateMinDate: {
                    valid: false
                }
            };
        }
    };
}
_

このようにフォームを開始します

_    this.definitionForm = this.fb.group({            
        "from": [this.details.From, Validators.required],
        "to": [this.details.To, [Validators.required, validateMinDate(this.details.From)]]
    });
_

バリデーターが適用されていることはわかりますが、バリデーターの最小値をconsole.log()すると、nullに等しいことがわかります。

_this.details.From_は、フォームを開始するとnullで始まるので、パラメーターは動的ではなく、フォームが設​​定されているときに値を取るだけだと思いますか?

ユーザーが開始日を選択したときに最小日付が更新されていることを確認して、_this.details.From_の値を変更するにはどうすればよいですか?

7
Nicolas

@Nicolas Validatorは、変更を検出しない場合にのみ値を取得します。したがって、値の変更時に新しいバリデーターを割り当てることで、パラメーター値を動的に変更できます。あなたの場合、あなたはこのようにすることができます:

_ onChanges(){
   var self=this;
    this.definitionForm.get('from').valueChanges.subscribe(val => {
     this.from=val;
     this.definitionForm.controls['to'].
     setValidators(Validators.compose([Validators.required, 
     TimeValidators.isTimeAfter(this.from)]));
})}
_

ここでは、時間を比較するための別のカスタムバリデーターを作成しました。これを使用するか、変更することができます

_import { FormControl, Validators,ValidatorFn, AbstractControl} from '@angular/forms';

export class TimeValidators extends Validators{

  static isTimeBefore(timeStr : string): ValidatorFn{
    return(c: AbstractControl): {[key:string]: boolean} | null => {
      if(c.value!==undefined && (isNaN(c.value)) || c.value > timeStr || c.value== timeStr){
        return {
          'isTimeBefore':true
        }
      }
      return null;
    }
  }
  static isTimeAfter(timeStr : string): ValidatorFn{
    return(c: AbstractControl): {[key:string]: boolean} | null => {
      if(c.value!==undefined && (isNaN(c.value)) && (c.value < timeStr || c.value == timeStr)){
        return {
          'isTimeAfter':true
        }
      }
      return null;
    }
  }
}
_

_definitionForm FormGroup_を初期化した後、onChanges()関数を呼び出します。

8

私の見方では、フォームグループにバリデーターを適用するか、大きなフォームがある場合は、fromtoのネストされたグループを作成し、バリデーターをに適用することをお勧めします。それ以外の場合は、変更が発生するたびにこのカスタムバリデーターが起動されます。したがって、バリデーターとフォームグループを次のように更新することを意味します。

this.definitionForm = this.fb.group({            
  "from": [this.details.From, Validators.required],
  "to": [this.details.To, [Validators.required]]
}, {validator: validateMinDate()});

export function validateMinDate(): ValidatorFn {
    return (c: AbstractControl) => {
      if(c) {
        let isValid = c.get('to').value >= c.get('from').value;
        if (isValid) {
            return null;
        } else {
            return {validateMinDate: true};
        }
      }
    };
}

もちろん、変更イベントをリッスンしてから日付のチェックを行うなど、他のオプションもあります。有効でない場合は、フォームでsetErrorsを使用してください。

3
AJT82