【问题标题】:Password match validation in reactive form in AngularAngular中反应形式的密码匹配验证
【发布时间】:2021-01-14 10:44:23
【问题描述】:

我有两个输入(newPasswordconfirmPassword),必须通过匹配来验证它们。 我有resetPasswordFormGroup,它在reset-password.component 中定义。

当我在 formgroup 中使用 MustMatch 自定义验证器时,我收到此错误。 实际上,我对如何使用自定义验证器感到困惑。

'{验证器类型的参数:(formGroup:FormGroup)=> void; }' 不可分配给类型为 'ValidatorFn | 的参数验证器Fn[] |抽象控制选项'。 对象字面量只能指定已知属性,而 'validator' 不存在于类型 'ValidatorFn |验证器Fn[] | AbstractControlOptions'.ts(2345)

resetPasswordFormGroup = new FormGroup({
        currentPassword: new FormControl(null, Validators.required),
        newPassword: new FormControl(null, Validators.required),
        confirmNewPassword: new FormControl(null, Validators.required),
    });

    get currentPasswordFormControl() {
        return this.resetPasswordFormGroup.get('currentPassword');
    }

    get newPasswordFormControl() {
        return this.resetPasswordFormGroup.get('newPassword');
    }

    get confirmNewPasswordFormControl() {
        return this.resetPasswordFormGroup.get('confirmNewPassword');
    }
        <form [formGroup]='resetPasswordFormGroup' (ngSubmit)="onPasswordChange()">
            <mat-card-content>
                <mat-form-field class="center-text">
                    <input matInput placeholder="please enter your current password" formControlName="currentPassword" />
                    <mat-error *ngIf="currentPasswordFormControl.hasError('required')">
                        <strong>current password</strong> is required
                    </mat-error>
                </mat-form-field>
                <mat-form-field class="center-text">
                    <input matInput placeholder="please enter your new password" formControlName="newPassword" />
                    <mat-error *ngIf="newPasswordFormControl.hasError('required')">
                        <strong> new password </strong> is required  
                    </mat-error>
                </mat-form-field>
                <mat-form-field class="center-text">
                    <input matInput placeholder="please confirm your new password"
                        formControlName="confirmNewPassword" />
                    <mat-error *ngIf="confirmNewPasswordFormControl.hasError('required')">
                         <strong> confirm new password</strong> is required
                    </mat-error>
                </mat-form-field>
            </mat-card-content>

            <mat-card-actions>
                <button mat-raised-button color="primary">
                    <div *ngIf="isSubmitting" class="loading">
                        <mat-spinner [diameter]="26" color="accent"></mat-spinner>
                    </div>
                    <span *ngIf="!isSubmitting">
                        submit
                    </span>
                </button>
            </mat-card-actions>
        </form>

【问题讨论】:

    标签: angular


    【解决方案1】:

    你做错了

    根据docs,您必须这样做:

    const form = new FormGroup({
      password: new FormControl('', Validators.minLength(2)),
      passwordConfirm: new FormControl('', Validators.minLength(2)),
    }, passwordMatchValidator);
    
    
    function passwordMatchValidator(g: FormGroup) {
       return g.get('password').value === g.get('passwordConfirm').value
          ? null : {'mismatch': true};
    }
    

    通过引用传递函数的位置

    或喜欢:

    const form = new FormGroup({
      password: new FormControl('')
      passwordConfirm: new FormControl('')
    }, { validators: passwordMatchValidator, asyncValidators: otherValidator });
    

    此外,如果您仍想通过传递控件名称来完成此操作,您可能会提出以下建议

    对于match-password.validator.ts

    import { FormGroup } from '@angular/forms';
        
    export function ConfirmedValidator(controlName: string, matchingControlName: string){
        return (formGroup: FormGroup) => {
            const control = formGroup.controls[controlName];
            const matchingControl = formGroup.controls[matchingControlName];
            if (matchingControl.errors && !matchingControl.errors.confirmedValidator) {
                return;
            }
            if (control.value !== matchingControl.value) {
                matchingControl.setErrors({ confirmedValidator: true });
            } else {
                matchingControl.setErrors(null);
            }
        }
    }
    
    

    然后就可以导入使用了

    import { Component } from '@angular/core';
    import { FormBuilder, FormGroup, FormControl, Validators} from '@angular/forms';
      
    import { ConfirmedValidator } from './match-password.validator';
        
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      form: FormGroup = new FormGroup({});
      
      constructor(private fb: FormBuilder) {
      
        this.form = fb.group({
          password: ['', [Validators.required]],
          confirm_password: ['', [Validators.required]]
        }, { 
          validator: ConfirmedValidator('newPassword', 'confirmNewPassword')
        })
      }
        
      get f(){
        return this.form.controls;
      }
    }
    

    Angular Validation Password and Confirm Password

    【讨论】:

    • 当我做你说的同样的事情时,我得到了这样的错误 core.js:6014 错误错误:未捕获(承诺):TypeError:无法读取 null 的属性“值” TypeError:无法读取FormGroup.passwordMatchValidator [as validator] (reset-password.component.ts:80) at FormGroup._runValidator (forms.js:4089) at FormGroup.updateValueAndValidity (forms.js:4050) at new FormGroup 的属性“值” (forms.js:4927) 在新的 ResetPasswordComponent (reset-password.component.ts:28)
    • 请展示你是如何做到的,完整的代码,并确保我使用g.get('password'),在你的代码中应该像g.get('newPassword')g.get('passwordConfirm')应该是g.get('confirmNewPassword')跨度>
    【解决方案2】:

    这对我不起作用,我尝试了多次,但我无法弄清楚为什么它不起作用。最后,我以这种方式做到了。谢谢各位。

    resetPasswordFormGroup: FormGroup;
    matcher = new MyErrorStateMatcher();
    
        constructor(
            private router: Router,
            private apiService: AuthApiService,
            private authSerivce: AuthService,
            private snackbar: MatSnackBar,
            private formbuilder: FormBuilder
        ) {
            this.resetPasswordFormGroup = this.formbuilder.group({
                currentPassword: ['', Validators.required],
                newPassword: ['', Validators.required],
                confirmPassword: ['', Validators.required],
            }, { validator: this.checkPasswords });
        }
    
    
        checkPasswords(group: FormGroup) {
            const pass = group.controls.newPassword.value;
            const confirmPass = group.controls.confirmPassword.value;
    
            return pass === confirmPass ? null : { notSame: true };
        }
    
    

    以及用于检查密码是否匹配的模板代码

            <form [formGroup]='resetPasswordFormGroup' (ngSubmit)="onPasswordChange()">
                <mat-card-content>
    
                    <mat-form-field class="center-text">
                        <input matInput placeholder="please enter your current password" formControlName="currentPassword"/>
                        <mat-error *ngIf="resetPasswordFormGroup.hasError('required', 'currentPassword')">
                            current password is required</mat-error>
                    </mat-form-field>
    
                    <mat-form-field class="center-text">
                        <input matInput placeholder="please enter your new password" formControlName="newPassword"/>
                        <mat-error *ngIf="resetPasswordFormGroup.hasError('required', 'newPassword')">
                            new password is required
                        </mat-error>
                    </mat-form-field>
    
                    <mat-form-field class="center-text">
                        <input matInput placeholder=" please confirm your new password" formControlName="confirmPassword"/>
                        <mat-error *ngIf="resetPasswordFormGroup.hasError('notSame')">
                            your new passwords are not match
                        </mat-error>
                        <mat-error *ngIf="resetPasswordFormGroup.hasError('required', 'confirmPassword')">
                            confirm new password is required
                        </mat-error>
                    </mat-form-field>
    
                </mat-card-content>
            </form>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      相关资源
      最近更新 更多