Javascript Angular 2自定义验证器如何设置control.valid true?

Javascript Angular 2自定义验证器如何设置control.valid true?,javascript,angularjs,typescript,angular,Javascript,Angularjs,Typescript,Angular,我有这样的自定义验证器: static isEmail(control:Control):{[key:string]:boolean} { let emailRegExp = new RegExp("^[-a-z0-9~!$%^&*_=+}{'?]+(.[-a-z0-9~!$%^&*_=+}{'?]+)*@([a-z0-9_][-a-z0-9_]*(.[-a-z0-9_]+)*.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|muse

我有这样的自定义验证器:

static isEmail(control:Control):{[key:string]:boolean} {
  let emailRegExp = new RegExp("^[-a-z0-9~!$%^&*_=+}{'?]+(.[-a-z0-9~!$%^&*_=+}{'?]+)*@([a-z0-9_][-a-z0-9_]*(.[-a-z0-9_]+)*.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}))(:[0-9]{1,5})?$", 'i');
  if (control.value.match(emailRegExp)) {
    return {isEmail: true};
  }
  return {isEmail: false};
}
static isPassword(control:Control):{[key:string]:boolean} {
  let passwordRegExp = new RegExp("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$");
  if (control.value.match(passwordRegExp)) {
    return null;
  }
  return {isPassword: false};
}
在组件中使用它:

loginForm:ControlGroup;

constructor(private _router:Router,
          private _loginService:LoginService,
          private _formBuilder:FormBuilder) {
this.loginForm = _formBuilder.group({
  email: ['', Validators.compose([
    Validators.required,
    Validators.minLength(8),
    FormValidationService.isEmail
  ])],
  password: ['', Validators.compose([
    Validators.required,
    Validators.minLength(8),
    Validators.maxLength(30),
    FormValidationService.isPassword
  ])]
 });
}
和模板:

 <form id="login-form" role="form" [ngFormModel]="loginForm" (ngSubmit)="onLoginSubmit()">
    <div class="form-group">
      <label class="control-label" for="loginFormEmail">Email</label>
      <input type="text" id="loginFormEmail" class="form-control"
             ngControl="email" #email="ngForm">
      <div *ngIf="email.dirty && !email.valid">
        <div class="alert alert-danger" role="alert" [hidden]="!email.errors.minlength">
          Email field must have more then 8 characters
        </div>
        <div class="alert alert-danger" role="alert" [hidden]="email.errors.isEmail">
          Email not valid
        </div>
      </div>
    </div>
    <div class="form-group">
      <label class="control-label" for="loginFormPassword">Password</label>
      <input type="password" id="loginFormPassword" class="form-control"
             ngControl="password" #password="ngForm">
      <div *ngIf="password.dirty && !password.valid">
        <div class="alert alert-danger" role="alert" [hidden]="!password.errors.minlength">
          Password field must have more then 8 characters
        </div>
        <div class="alert alert-danger" role="alert" [hidden]="!password.errors.maxlength">
          Password field must have no more then 30 characters
        </div>
        <div class="alert alert-danger" role="alert" [hidden]="password.errors.isPassword">
          Password must meet the following rules:
          <ul>
            <li>At least one upper case english letter</li>
            <li>At least one lower case english letter</li>
            <li>At least one digit</li>
            <li>At least one special character</li>
          </ul>
        </div>
      </div>
    </div>
    <p>If you forgot your password you can <a (click)="toForgot()">reset it</a>.</p>
    <div class="form-group">
      <button type="submit" class="btn btn-primary btn-block" [disabled]="!loginForm.valid">Login</button>
    </div>
  </form>

电子邮件
电子邮件字段必须超过8个字符
电子邮件无效
密码
密码字段必须超过8个字符
密码字段不能超过30个字符
密码必须符合以下规则:
  • 至少一个大写英文字母
  • 至少一个小写英文字母
  • 至少一位数字
  • 至少有一个特殊字符
如果你忘记了密码,你可以


我试图设置
control.valid=true
,但此字段只有getter。

我认为您需要将
ngControlGroup
添加到包装元素中,否则表单将无法跟踪包含的输入元素

<div class="form-group" ngControlGroup="someName">


另请参见使用FormBuilder类将内联表单定义与ngForm和JS代码中的定义混合在一起

您应该以这种方式重构输入定义,以使用ngFormControl指令:

<input [ngFomControl]="loginForm.controls.password" .../>

我找到了答案。当控件值有效时,您必须在自定义验证器中返回null:

static isEmail(control:Control):{[key:string]:boolean} {
  let emailRegExp = new RegExp("^[-a-z0-9~!$%^&*_=+}{'?]+(.[-a-z0-9~!$%^&*_=+}{'?]+)*@([a-z0-9_][-a-z0-9_]*(.[-a-z0-9_]+)*.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}))(:[0-9]{1,5})?$", 'i');
  if (control.value.match(emailRegExp)) {
    return {isEmail: true};
  }
  return {isEmail: false};
}
static isPassword(control:Control):{[key:string]:boolean} {
  let passwordRegExp = new RegExp("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$");
  if (control.value.match(passwordRegExp)) {
    return null;
  }
  return {isPassword: false};
}

我认为你是对的。但现在它对我不起作用了。我想你忘了更新你的ngIfs(“loginForm.controls.password.dirty&&!login.controls.password.valid”例如),并在表达式中使用Elvis运算符隐藏:“loginForm.controls.password.errors?.isPassword”例如。我在docs方法setErrors()中找到了其他人用过它吗?