Как я могу получить Validators непосредственно из formControl? - PullRequest
0 голосов
/ 01 июня 2018

enter image description here

enter image description here

enter image description here

У меня естьполе электронной почты, и я добавил два валидатора (обязательно для электронной почты), я хочу проверить статус валидации на input event, чтобы вызвать API, проверить дозу члена моей системы, когда он действителен, если invalid не звонитьAPI и не отображать сообщение об ошибке на странице.

Я покажу сообщение об ошибке в событии размытия (ввод электронной почты focusOut), сначала я использовал formControl.validator(formControl) для запуска валидаторов и проверки formControl.valid, я получил действительныйстатус успешен, но на странице будет отображаться сообщение об ошибке, потому что я подписался на statsuChange, чтобы отображать сообщение об ошибке, когда в настоящее время статус равен invalid.

, я сохраняю валидаторы в переменной и передаю initEmailChaingeEvent() дляпроверить статус проверки без события statusChange.Это может работать, но я думаю, что это не очень хороший способ, вот пример моей реализации:

живой пример

export class AppComponent {
  public sampleForm: FormGroup;

  @ViewChild('emailElm')
  emailElm: ElementRef;

  ngOnInit() {
    this.initForm();
  }

  initForm() {
    const emailValidtors = [
      Validators.required,
      Validators.email
    ]

    const emailFC = new FormControl(null, {
      validators: emailValidtors,
      updateOn: 'blur'
    });
    //
    this.sampleForm = new FormGroup({
      'email': emailFC
    });
    //
    this.initEmailChaingeEvent({
      emailFC: emailFC,
      validtors: emailValidtors
    });
    //
    this.sampleForm.valueChanges.subscribe((val) => {
      console.log('_blue event:valueChanges', val)
    });
    //
    this.initShowErrorMsgEvent({
      fc: emailFC
    });
  }

  private initEmailChaingeEvent(arg: {
    emailFC: FormControl,
    validtors: any[]
  }) {
    fromEvent(this.emailElm.nativeElement, 'input')
      .pipe(debounceTime(500))
      .subscribe((event: Event) => {
        const currentEmail = (event.target as HTMLInputElement).value;
        // check is valid
        // **quention** : how can I get validtors from fromcontrol self 
        // if I use  arg.emailFC.validator(arg.emailFC) to ehcek status , it will trigger oberservable in initShowErrorMsgEvent(),
        //  but I just want to got valid result , I don't want to show error msg on UI at this time

        for (const validator of arg.validtors) {
          const inValid = validator(arg.emailFC);
          if (inValid) {
            console.log('input event:invalid', currentEmail);
            return;
          }
        }
        // **do sometheng when all valid**
        console.log('input event:call API , email:',currentEmail );
      });
  }

  private initShowErrorMsgEvent(arg: {
    fc: FormControl,
  }) {
    arg.fc.statusChanges
      .subscribe((status) => {
        // console.log('status' , status);
        if (status === 'INVALID') {
          // show error msg....
          console.log('_show error msg by antoher component');
        }
      });
  }
}
<form [formGroup]="sampleForm">
  <input formControlName="email" #emailElm >
</form>

Ответы [ 3 ]

0 голосов
/ 07 июня 2018

Вы слишком усложнили задачу.Сначала объявите вашу форму и управляйте валидаторами.Если вы составите валидатор из списка валидаторов, они будут проверены в порядке определения.Итак, сначала требуемый, затем «если это действительный адрес электронной почты», и, наконец, пользовательский валидатор проверит, является ли он уникальным

 ....
 this.emailForm = this.fb.group({
       emailAddress: [null, Validators.compose([Validators.required, Validators.email, uniqueEmailValidator()])]
 });
 ...

Затем вы создадите свой собственный валидатор для проверки электронной почты пользователя с помощью API.Больше информации о пользовательских валидаторах: Угловые документы

function uniqueEmailValidator(){
    ...
}
0 голосов
/ 11 июня 2018

спасибо всем, дайте мне больше идей, я исправил это через свойство validator formControl, это мой измененный список:

  • только передает значение валидаторам, избегая триггера statusChange emitter

живой пример

private initEmailChaingeEvent(arg:{
   emailFC : FormControl,
   ....
}) {
  ...
  const inValid = arg.emailFC.validator({
      value: currentEmail
    }
    as any);
  ....
}
0 голосов
/ 05 июня 2018

Здесь много чего нужно, чтобы поработать.Во-первых, я бы подписался на изменения formValue элемента управления вместо использования Observable для собственного элемента.

this.sampleForm.get('email').valueChanges.subscribe((event) => {
    // CODE IN HERE
}

ValueChanges - это свойство в formControl, которое генерирует событие при изменении значения.https://angular.io/api/forms/AbstractControl

Далее, чтобы получить доступ к валидаторам, вы можете просто проверить элемент управления формы, если он действителен.

this.sampleForm.get('email').valid();

Если какой-либо валидатор недействителен, это будет false, если всевалидаторы действительны, это будет правда.

РЕДАКТИРОВАТЬ:

Из вашего комментария звучит так, как будто вы хотите, чтобы там была труба debounceTime:

this.sampleForm.get('email').valueChanges
.pipe(debounceTime(500), distinctUntilChanged())
.subscribe((event) => {
    if (this.sampleForm.get('email').valid) {
         // Your API logic here
    }
}

DebounceTime в основном задерживаетсобытие обрабатывается и отбрасывает все ожидающие события в очереди.

debounceTime задерживает значения, испускаемые источником Observable, но отбрасывает предыдущие отложенные отсроченные выбросы, если новое значение поступает в источник Observable.http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-debounceTime

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...