Validation 如何手动将角度形式字段设置为无效?

Validation 如何手动将角度形式字段设置为无效?,validation,angular,angular2-forms,Validation,Angular,Angular2 Forms,我正在处理一个登录表单,如果用户输入的凭据无效,我们希望将电子邮件和密码字段都标记为无效,并显示一条消息,说明登录失败。如何从可观察回调中将这些字段设置为无效 模板: 电子邮件地址或密码无效 记得我吗 忘记密码了? 登录 没有帐户吗?单击此处创建帐户 登录方式: @ViewChild('loginForm')loginForm:HTMLFormElement; 私有登录(formData:any):无效{ this.authService.login(formData.subscribe)(

我正在处理一个登录表单,如果用户输入的凭据无效,我们希望将电子邮件和密码字段都标记为无效,并显示一条消息,说明登录失败。如何从可观察回调中将这些字段设置为无效

模板:


电子邮件地址或密码无效

记得我吗 忘记密码了? 登录

没有帐户吗?
单击此处创建帐户

登录方式:

@ViewChild('loginForm')loginForm:HTMLFormElement;
私有登录(formData:any):无效{
this.authService.login(formData.subscribe)(res=>{
警报(祝贺你,你已经登录了。我们现在没有任何地方可以发送给你,但不管怎样祝贺你!`);
},错误=>{
this.loginFailed=true;//这会显示错误消息,我不太喜欢这样,但这是另一个问题。
this.loginForm.controls.email.invalid=true;
this.loginForm.controls.password.invalid=true;
});
}
除了将inputs invalid(输入无效)标志设置为true之外,我还尝试将
email.valid
标志设置为false,并将
loginForm.invalid
设置为true。所有这些都不会导致输入显示其无效状态。

在组件中:

formData.form.controls['email'].setErrors({'error':true});
和HTML格式:


{{email.errors | json}}

补充朱莉娅·帕辛科娃的答案

要在组件中设置验证错误,请执行以下操作:

formData.form.controls['email'].setErrors({'error':true});
要取消组件中的验证错误,请执行以下操作:

formData.form.controls['email'].setErrors(null);
请小心使用
null
取消设置错误,因为这将覆盖所有错误。如果要保留一些错误,可能需要先检查是否存在其他错误:

if(isincorrectonlyrror){
formData.form.controls['email'].setErrors(null);
}

在material 2的新版本中,其控制名称以mat前缀setErrors()开头不起作用,相反,Juila的答案可以更改为:

formData.form.controls['email'].markAsTouched();

我试图在模板表单中的ngModelChange处理程序中调用
setErrors()
。直到我用
setTimeout()
等待一个勾号,它才开始工作:

模板:


密码不匹配
组成部分:

@ViewChild('pwconfirmfodel')pwconfirmfodel:NgModel;
检查密码(){
如果(this.pwConfirm.length>=this.user.password.length&&
this.pwConfirm!==this.user.password){
log(“密码不匹配”);
//必须在运行更改检测后调用setErrors()
setTimeout(()=>this.pwConfirmModel.control.setErrors({'nomatch':true}));
}否则{
//要清除错误,我们不必等待
this.pwConfirmModel.control.setErrors(null);
}
}

像这样的怪癖让我更喜欢反应形式。

下面是一个有效的例子:

MatchPassword(AC: FormControl) {
  let dataForm = AC.parent;
  if(!dataForm) return null;

  var newPasswordRepeat = dataForm.get('newPasswordRepeat');
  let password = dataForm.get('newPassword').value;
  let confirmPassword = newPasswordRepeat.value;

  if(password != confirmPassword) {
    /* for newPasswordRepeat from current field "newPassword" */
    dataForm.controls["newPasswordRepeat"].setErrors( {MatchPassword: true} );
    if( newPasswordRepeat == AC ) {
      /* for current field "newPasswordRepeat" */
      return {newPasswordRepeat: {MatchPassword: true} };
    }
  } else {
    dataForm.controls["newPasswordRepeat"].setErrors( null );
  }
  return null;
}

createForm() {
  this.dataForm = this.fb.group({
    password: [ "", Validators.required ],
    newPassword: [ "", [ Validators.required, Validators.minLength(6), this.MatchPassword] ],
    newPasswordRepeat: [ "", [Validators.required, this.MatchPassword] ]
  });
}

虽然很晚了,但下面的解决方案对我有效

    let control = this.registerForm.controls['controlName'];
    control.setErrors({backend: {someProp: "Invalid Data"}});
    let message = control.errors['backend'].someProp;
对于单元测试:

spyOn(component.form, 'valid').and.returnValue(true);

在我的反应式表单中,如果检查了另一个字段,我需要将该字段标记为无效。在ng版本7中,我执行了以下操作:

    const checkboxField = this.form.get('<name of field>');
    const dropDownField = this.form.get('<name of field>');

    this.checkboxField$ = checkboxField.valueChanges
        .subscribe((checked: boolean) => {
            if(checked) {
                dropDownField.setValidators(Validators.required);
                dropDownField.setErrors({ required: true });
                dropDownField.markAsDirty();
            } else {
                dropDownField.clearValidators();
                dropDownField.markAsPristine();
            }
        });
const checkboxField=this.form.get(“”);
const dropDownField=this.form.get(“”);
this.checkboxField$=checkboxField.valueChanges
.subscribe((选中:布尔)=>{
如果(选中){
setValidators(Validators.required);
setErrors({required:true});
dropDownField.markAsDirty();
}否则{
clearValidators();
markAsPristine();
}
});
如上所述,当我选中该框时,它会根据需要设置下拉列表,并将其标记为脏。如果您没有这样标记,那么在您尝试提交表单或与表单交互之前,表单不会无效(错误)

如果复选框设置为false(未选中),那么我们在下拉列表中清除所需的验证器,并将其重置为原始状态


另外-请记住取消订阅监控字段更改

您还可以将viewChild“type”更改为NgForm,如下所示:

@ViewChild('loginForm') loginForm: NgForm;
然后以@Julia提到的相同方式引用控件:

 private login(formData: any): void {
    this.authService.login(formData).subscribe(res => {
      alert(`Congrats, you have logged in. We don't have anywhere to send you right now though, but congrats regardless!`);
    }, error => {
      this.loginFailed = true; // This displays the error message, I don't really like this, but that's another issue.

      this.loginForm.controls['email'].setErrors({ 'incorrect': true});
      this.loginForm.controls['password'].setErrors({ 'incorrect': true});
    });
  }
将错误设置为null将清除UI上的错误:

this.loginForm.controls['email'].setErrors(null);

您的后端是否位于与angular不同的端口上?如果是这样,这可能是CORS的问题。您在后端使用什么框架。您可以使用
setErros
方法。提示:您应该在组件文件中添加所需的验证器。还有一个具体的原因是使用ngModel处理被动表单吗?@developer033在这里参加聚会有点晚,但是这些表单看起来不像被动表单,而是模板驱动的表单。之后如何消除错误
setErrors({'error':false})
setErrors({})
不适用于meCan我可以将整个反应式表单设置为有效或无效,而不是重置字段吗?@Robouste您可以通过
setErrors(null)
手动删除错误,此外,还可以回答:如果没有
formData.form.controls,此代码对我不起作用['email'].markAsTouched();
如下面提到的@M.Farahmand。使用
setErrors({'error':true})
只需设置
ng invalid
css类进行输入。我希望这对某些人有所帮助。如果有更多的验证器,比如“required”—setErrors(null)呢删除该错误?是否可以使用类似formData.form.controls['email'].setErrors({'error':false})的东西取消验证错误;反应式表单如何?这可能是“黑客行为”,但我喜欢它,因为您不必设置自定义ErrorStateMatcher来处理角度材质输入错误!
找不到名称“NgModel”。
错误