Проверка правильности формы Angular2 зависит от внешнего свойства формы - PullRequest
1 голос
/ 30 января 2020

Я использовал некоторые валидаторы в angular2, такие как валидатор равных паролей. В этом сценарии ios оба элемента управления находятся в одной форме, и я могу получить доступ к обоим элементам управления в методе проверки директивы.

Но в моем сценарии у формы есть один элемент управления формы с именем Email и требуется только тогда, когда EmailFlag верно. EmailFlag не является элементом управления формой и будет обновлять его значение в любое время. Я обрабатываю значение изменения EmailFlag в ngOnChanges валидатора и обрабатываю изменение Email в методе валидатора валидатора.

Я могу получить доступ и установить валидацию для управления формой только при вызове метода validate. Но при смене флага я не могу получить контроль формы и установить для него проверку. Есть ли способ получить контроль формы при смене флага и проверке достоверности?

Директива

@Directive({
  selector: '[requiredIfTrue]',
  providers: [{
    provide: NG_VALIDATORS,
    useExisting: RequiredIfTrueValidator,
    multi: true
  }]
})
export class RequiredIfTrueValidator implements OnChanges {
  _emailFlag: boolean;
  @Input('requiredIfTrue') public requiredIfTrue: boolean;

  validate(control: AbstractControl): { [key: string]: any } | null {
    if (this._emailFlag) {
      //set validation
    }
    else {
      //remove validation
    }
  }

  ngOnChanges(change: SimpleChanges) {
    if (change.requiredIfTrue) {
      this._emailFlag = change.requiredIfTrue.currentValue;
    }
  }
}

component.ts

EmailFlag = false;
//flag declared and changes value time by time

компонент. html

<input type="text" formControlName="Email" class="form-control" [requiredIfTrue]="EmailFlag" />

Ответы [ 3 ]

1 голос
/ 30 января 2020

Inject NgControl внутри пользовательской директивы для получения экземпляра директивы FormControl внутри пользовательской директивы, подобной этой

import { Directive, OnInit, Input } from '@angular/core';
import { NgControl, Validators } from '@angular/forms';
@Directive({
  selector: '[RequiredIfTrue]'
})
export class RequiredIfTrueDirective{
  @Input('RequiredIfTrue') set requited(value){
    console.log(value);
    if(value){
       this.control.control.setValidators(this.control.control.validator ? [this.control.control.validator, Validators.required] : Validators.required );
       this.control.control.updateValueAndValidity();
    }else{
            this.control.control.clearValidators();
            this.control.control.updateValueAndValidity();
    }
  };
  constructor(private control:NgControl) {

   }
}

Рабочий пример

1 голос
/ 30 января 2020

Если вы хотите использовать валидатор, который в зависимости от переменной в вашем .ts, вы можете использовать bind (this)

emailFlag:boolean=true;
email=new FormControl("email",this.requiredIf().bind(this))

requiredIf()
  {
    return (control)=>{
      return this.emailFlag?!control.value?{required:true}:null:null
    }
  }

Будьте осторожны, когда вы изменяете переменную, вам нужно сделать updateValueAndValidity

click(){
   this.EmailFlag=!this.EmailFlag
   this.email.updateValueAndValidity()
}

см. stackblitz

ПРИМЕЧАНИЕ. Я использую способ this.requiredIf, чтобы разрешить, например, если у вас есть массив required=[true,false,false,true], передать «индекс» "к функции

Это

<form [formGroup]="form">
  <input formControlName="one">
  <small *ngIf="form.get('one').invalid">*</small>
  <button (click)="clickArray(0)">click</button>
  required:{{required[0]}}<br/>
    <input formControlName="two">
    <small *ngIf="form.get('two').invalid">*</small>
    <button (click)="clickArray(1)">click</button>
    required:{{required[1]}}<br/>
  <input formControlName="three">
  <small *ngIf="form.get('three').invalid">*</small>
  <button (click)="clickArray(2)">click</button>
  required:{{required[2]}}<br/>
</form>

И вы меняете как

form = new FormGroup({
    one: new FormControl("", this.requiredIfArray(0).bind(this)),
    two: new FormControl("", this.requiredIfArray(1).bind(this)),
    three: new FormControl("", this.requiredIfArray(2).bind(this))
  });

requiredIfArray(index) {
  return control => {
    return this.required[index]? !control.value? { required: true }: null: null;
  };
}
0 голосов
/ 30 января 2020

Вы можете принудительно проверить правильность, используя updateValueAndValidity . Вы также можете запустить его в formGroup. Смотрите здесь: https://netbasal.com/three-ways-to-dynamically-alter-your-form-validation-in-angular-e5fd15f1e946

...