如何直接从formControl获取Validators?

时间:2018-06-01 15:59:14

标签: angular angular5 angular6 angular-forms

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事件。 它可以工作,但我认为这不是一个好方法,这是我实施的一个例子:

live example



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>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:2)

你过度复杂的任务。 首先,声明您的表单,并控制验证器。如果您从验证器列表中组成验证器,则将按照定义检查它们。所以,首先是必需的,然后“如果它是有效的电子邮件”,最后你自定义验证器将检查它是否是唯一的

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

然后,您创建自定义验证程序,以便通过API检查用户电子邮件。有关自定义验证程序的更多信息:Angular docs

function uniqueEmailValidator(){
    ...
}

答案 1 :(得分:0)

这里有很多需要一些工作的东西。首先,我会订阅控件的formValue更改,而不是在本机元素上使用Observable。

def inser_node (self, node: 'Tree'):

ValueChanges是formControl上的一个属性,它在值更改时发出事件。 https://angular.io/api/forms/AbstractControl

接下来,要访问验证器,只需检查表单控件是否有效。

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

如果任何验证器无效,则该值为false,如果所有验证器都有效,则为真。

编辑:

从你的评论中,听起来你想要一个debounceTime管道:

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

DebounceTime基本上会延迟处理事件,并会丢弃队列中的任何待处理事件。

  

debounceTime会延迟源Observable发出的值,但如果新值到达源Observable,则会丢弃先前待处理的延迟发射。 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-debounceTime

答案 2 :(得分:0)

感谢大家给我更多的想法,我通过formControl's validator属性修复了它,它是我的修改后的列表:

  • 仅将值传递给验证器,以避免触发statusChange发射器

live example

&#13;
&#13;
private initEmailChaingeEvent(arg:{
   emailFC : FormControl,
   ....
}) {
  ...
  const inValid = arg.emailFC.validator({
      value: currentEmail
    }
    as any);
  ....
}
&#13;
&#13;
&#13;