简体   繁体   English

如何在 angular 上向反应性 forms 添加特定验证

[英]How do I add specific validation to reactive forms on angular

I'm trying to render a div based on specific errors, my form works but is buggy and is trowing a type error, "undefined is not an object", and i don't understand why;我正在尝试根据特定错误渲染一个 div,我的表单可以工作,但是有问题并且出现类型错误,“未定义不是对象”,我不明白为什么; can someone help me understand what I'm missing?有人可以帮助我了解我所缺少的吗? I've tried simplifying my code by using just the.errors propery, that takes the errors away but its not specific enough to so that it knows what error to render depending on the state of the form, any insight would be super helpful:)我已经尝试通过仅使用 .errors 属性来简化我的代码,这可以消除错误,但它不够具体,以至于它知道要根据表单的 state 呈现什么错误,任何见解都会非常有帮助:)

HTML HTML

    <form  [formGroup]="form">
    <div class="spacer">
  <label for="oldPassword">Old Password</label><br /><input
    type="text"
    class="form-control"
    id="oldPassword"
    formControlName="oldPassword"
  />
      <div class="alert alert-danger" *ngIf="form.get('oldPassword').errors.passwordValidator">Duplicate Password</div>
      <div class="alert alert-danger" *ngIf="form.get('oldPassword').touched && form.get('oldPassword').errors.required">Old Password is Required</div>
      <div *ngIf="forms.get('oldPassword').pending">Loading...</div>
</div>
<div class="spacer">
  <label for="newPassword">New Password</label><br /><input
    type="text"
    class="form-control"
    id="newPassword"
    formControlName="newPassword"
  />
  <div *ngIf="form.get('newPassword').touched && newPassword.invalid" class="alert alert-danger">New Password is Required</div>
</div>
<div class="spacer">
  <label for="confirmPassword">Confirm Password</label><br /><input
    type="text"
    class="form-control"
    id="confirmPassword"
    formControlName="confirmPassword"
  />
  <div *ngIf="confirmPassword.touched && confirmPassword.invalid" class="alert alert-danger">Confirm Password is Required</div>
</div>
  <button class="btn btn-primary" (click)="onClick()">Submit!</button>
</form>

{{ oldPassword | json}}

TS: TS:

import { Component } from '@angular/core';
import { FormBuilder, Validators, FormGroup, FormControl,} from '@angular/forms'
import { CustomValidators } from '../passwordValidator';

@Component({
  selector: 'app-form',
  templateUrl: './form.component.html',
  styleUrls: ['./form.component.css']
})
export class FormComponent {
form = new FormGroup({
  oldPassword: new FormControl('',Validators.required, CustomValidators.passwordValidator),
  newPassword: new FormControl('',Validators.required),
  confirmPassword: new FormControl('',Validators.required)

})

onClick() {
  console.log(this.form.get('oldPassword').errors)
}
}


//CustomValidators.passwordValidator

CUSTOM VALIDATOR.TS自定义验证器.TS

import { AbstractControl, ValidationErrors, } from '@angular/forms';


export class CustomValidators {
    static passwordValidator(control: AbstractControl): Promise<ValidationErrors | null> {

        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (control.value === "123") {
                    resolve({ passwordValidator: true })
                }
                resolve(null)
            }, 2000);
        });


    }
}

Here is the error这是错误

You have some issues...你有一些问题...

  • <div *ngIf="forms.get('oldPassword').pending">Loading...</div> , remove the s from forms <div *ngIf="forms.get('oldPassword').pending">Loading...</div> ,从forms中删除s
  • <div *ngIf="confirmPassword.touched && confirmPassword.invalid" is invalid <div *ngIf="confirmPassword.touched && confirmPassword.invalid"无效
  • *ngIf="form.get('newPassword').touched && newPassword.invalid" is invalid *ngIf="form.get('newPassword').touched && newPassword.invalid"无效
  • Your custom async validator should be placed as the third argument您的自定义异步验证器应作为第三个参数
  • Those undefined issues stem from errors being null这些undefined的问题源于errorsnull

Suggestion: Use FormBuilder instead of calling new FormControl() , but I'll keep my sample with your current code.建议:使用FormBuilder而不是调用new FormControl() ,但我会将我的示例与您当前的代码一起保留。 Also usually we use ngSubmit instead of click event in forms.通常我们在 forms 中使用ngSubmit而不是点击事件。

So first place the async validator in correct place:所以首先将异步验证器放在正确的位置:

oldPassword: new FormControl(
  "",
  [Validators.required],
  [CustomValidators.passwordValidator]
),

The rest of the errors is related to that errors being null in template if there are no errors... where you are calling such as...如果没有错误,则错误的 rest 与模板中的errors为 null 相关...您在哪里调用例如...

*ngIf="form.get('oldPassword').errors.passwordValidator"

You could solve this by adding the safe navigation operator:可以通过添加安全导航运算符来解决此问题:

*ngIf="form.get('oldPassword').errors?.passwordValidator"

That will work, but I use the following way, which is in my opinion nicer and more intuitive:这会起作用,但我使用以下方式,在我看来这更好更直观:

*ngIf="form.hasError('passwordValidator', 'oldPassword')"

So here's a stripped down, shortened version of your code:因此,这是您的代码的精简版:

<form [formGroup]="form" (ngSubmit)="onClick()">
  <label for="oldPassword">Old Password</label><br />
  <input formControlName="oldPassword" />
  <div *ngIf="form.hasError('passwordValidator', 'oldPassword')">
    Duplicate Password
  </div>
  <div *ngIf="form.get('oldPassword').touched && form.hasError('required', 'oldPassword')">
     Old Password is Required
  </div>
  <div *ngIf="form.get('oldPassword').pending">Loading...</div>
  <button type="submit" [disabled]="!form.valid">Submit!</button>
</form>

STACKBLITZ 堆栈闪电战

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM