Angular2 - 模糊的FormControl验证

时间:2015-11-23 08:49:15

标签: validation typescript angular

我正在考虑添加一些基本的电子邮件验证,以检查用户是否输入了正确的电子邮件地址。目前使用下面的方法,验证会在用户输入时更新,在输入一个字符后出错时看起来很奇怪。

validEmail(c: Control){
if(!c.value.match('[a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?')){
  return {
    validEmail: true
  };
}
return null;
}    

ctrlEmailAddress: Control = new Control('', Validators.compose([
Validators.required, this.validEmail]));

我想知道是否有可能触发对场的模糊进行验证,例如在angularJS中:

ng-model-options="{ updateOn: 'blur' }"

我知道html中输入字段上的blur选项,但除非有办法将控件置于错误状态,否则不会将我的控件置于错误中。

有人能帮我指出正确的方向吗?

感谢。

编辑:我正在寻找angular2解决方案,而不是angularJS解决方案。

6 个答案:

答案 0 :(得分:46)

编辑2

正如Alexofficial documentation所说, Angular版本5.0.0 为您的ngModel protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack) { hfid.value="0"; } frmSubmit.Attributes.Add("onclick", "this.disabled = true; this.value = 'Loading ...'; " + ClientScript.GetPostBackEventReference(frmSubmit, null) + ";"); } protected void frmSubmit_Click(object sender, EventArgs e) { //Remove following line, this is added just to test. System.Threading.Thread.Sleep(5000); if (Convert.ToInt32(hfid.Value) == 0) { // Code of insert // then I set hfid.value with newly created id } }

提供了新选项
updateOn: 'blur'

您还可以使用其他更新选项:this.email = new FormControl(null, { validators: Validators.required, updateOn: 'blur' }); (默认),changeblur

<强>原始

我使用指令去除焦点上的整体验证并在模糊事件后将其返回。它基于Cristian Deschamps的答案。

我仅在模糊时更新有效性,因此如果在焦点之前值无效,则之后无效。但是如果你开始输入,有效期将会更新。

由于某些原因清算顺序有意义,所以我先清除异步验证器。

任何提供的建议都会有所帮助=)

submit

此外,请继续关注此Angular 2 github thread关于onBlur验证

编辑1

还有另一个问题 - 如果我只是点击该字段并在点击之后 - 将调用验证。如果您有任何关于它(或服务器调用)的通知 - 每次执行时都会出现。所以你可以添加import { Directive } from '@angular/core'; import { NgControl } from '@angular/forms'; @Directive({ selector: '[validate-onblur]', host: { '(focus)': 'onFocus($event)', '(blur)': 'onBlur($event)' } }) export class ValidateOnBlurDirective { private validators: any; private asyncValidators: any; constructor(public formControl: NgControl) { } onFocus($event) { this.validators = this.formControl.control.validator; this.asyncValidators = this.formControl.control.asyncValidator; this.formControl.control.clearAsyncValidators(); this.formControl.control.clearValidators(); } onBlur($event) { this.formControl.control.setAsyncValidators(this.asyncValidators); this.formControl.control.setValidators(this.validators); this.formControl.control.updateValueAndValidity(); } } 属性并像这样使用它:

wasChanged

答案 1 :(得分:13)

Angular v 5.0.0 开始,现在可以通过将updateOn: 'blur'标记为表单控件来实现。

这也意味着在模糊事件发生之前,valueChanges不会为该窗体控件触发。以下是minlengthrequired的示例:

this.form = new FormGroup({
  username: new FormControl('', {
  validators: [Validators.required, Validators.minLength(6)], updateOn: 'blur'} )
})

get username() {
  return this.form.get('username');
}

在模板中,您希望标记验证邮件不会显示,除非该字段为touched

<div *ngIf="username.hasError('minlength') || username.hasError('required') 
              && username.touched">Required and minlength 6!
</div>

<强> DEMO

P.S如果需要,您也可以在整个表单上标记,而不仅仅是在特定的表单控件上

答案 2 :(得分:8)

找到一种方法,在rc6。

1-创建指令:validate-onblur.directive.ts

@Directive({
  selector: '[validate-onblur]',
  host: {
    '(focus)': 'onFocus($event)',
    '(blur)': 'onBlur($event)'
  }
})
export class ValidateOnBlurDirective {
    constructor(public formControl: NgControl) {
    }

    onFocus($event) {
      this.formControl.control.markAsUntouched(false);
    }

    onBlur($event) {
      this.formControl.control.markAsTouched(true);
    }
}

然后在你的html模板中只需将指令添加到表单中,我的示例使用ReactiveFormsModule模型。

然后将此添加到您的错误消息中:

<input type="text" formControlName="full_name" validate-onblur />

<span *ngIf="formAccountDetails.controls.full_name.touched && !formAccountDetails.controls.full_name.valid && !formAccountDetails.controls.full_name.pristine" class="errors">
        ...
</span>

答案 3 :(得分:7)

这样的事情:  使用 ngControl 对象的 触及 属性。

 <div class="form-group" [class.has-error]="!name.valid && name.touched">
        <label for="name">Name</label>
        <input #name="ngForm" ngControl="name" name="name" type="text" class="form-control" required>
 </div>

答案 4 :(得分:4)

我已经改进了一些Alex Shestakov解决方案,它已经顺便使用了,以避免在控制状态值保持焦点的同时将其设置为有效。

@Directive({
    selector: '[validate-onblur]',
    host: {
        '(focus)': 'onFocus($event)',
        '(blur)' : 'onBlur($event)'
    }
})
export class ValidateOnBlurDirective {

    private validators: any;
    private asyncValidators: any;
    private hasFocus = false;

    constructor(public formControl: NgControl) {
    }

    onFocus($event) {
        this.hasFocus = true;
        this.validators = this.formControl.control.validator;
        this.asyncValidators = this.formControl.control.asyncValidator;
        this.formControl.control.clearAsyncValidators();
        this.formControl.control.clearValidators();
        this.formControl.control.valueChanges
            .filter(() => this.hasFocus)
            .subscribe(() => this.formControl.control.markAsPending());
    }

    onBlur($event) {
        this.hasFocus = false;
        this.formControl.control.setAsyncValidators(this.asyncValidators);
        this.formControl.control.setValidators(this.validators);
        this.formControl.control.updateValueAndValidity();
    }
}

这样,只要控件保持焦点,控件就会保持挂起状态。这将有助于避免控件在获得焦点之前无效的情况,然后一旦用户开始在其上键入,它就被标记为有效,在模糊事件发生之前,再次设置验证器并且实际有效性为控制应该确定。

答案 5 :(得分:-7)

你可以

[class.has-error]="!form.controls['ctrlEmailAddress'].valid"

只要您更改模型,就会添加has-error类。所以基本上你不需要模糊以进行验证检查。

这解决了角度2.0.0 beta的问题;)