【问题标题】:Validating Same Password Input Angular 2/4 - ERROR Cannot find control with unspecified name attribute验证相同的密码输入 Angular 2/4 - 错误找不到具有未指定名称属性的控件
【发布时间】:2017-10-16 04:01:45
【问题描述】:

我正在尝试验证我的表单中的密码和 ConfirmPassword 字段是否相同,但是当我在 SO 上添加其他帖子提供的验证时(除了将 ControlGroup 更改为 FormGroup)我不断得到

错误:找不到具有未指定名称属性的控件

但是,当我不使用下面的“matchingPassword”组进行验证而只使用 Validators.required 语法时,它工作得很好。

我不知道它为什么会抛出这个错误。有没有其他人解决过这个问题?我目前正在构建 Angular 4 Distro。

constructor(
private accountService: accountService,
fb: FormBuilder,
) {
    this.changePWForm = fb.group({
        'CurrentPassword' : [null, Validators.required],
        'SecurityQuestions' : [null, Validators.required],
        'SecurityQuestionAnswer' : [null, Validators.required],
         'matchingPassword': fb.group({
                'NewPassword' : [null, Validators.compose([Validators.pattern(this.strongPW), Validators.required])],
                'ConfirmPassword' : [{disabled: true}, Validators.required],
            }, {validator: this.equalPasswords})

    })


}

equalPasswords(group: FormGroup){
   //When I use the syntax above, it never makes it here.
    var valid = false;

        for (var name in group.controls) {
            var val = group.controls[name].value


        }

        if (valid) {
            return null;
        }

        return {
            areEqual: true
        };

}

这是我的 HTML 模板

 <form [formGroup]="changePWForm" (ngSubmit)="updatePW(changePWForm.value)" *ngIf="securityQuestions">
            <div class="form-group">
            <label>Current Password:</label>
            <input type="text" [(ngModel)]="changePWData.CurrentPassword" [formControl]="changePWForm.controls['CurrentPassword']">
            </div>
            <div class="form-group">
            <label>New Password:</label>
            <input type="text" [(ngModel)]="changePWData.NewPassword" [formControl]="changePWForm.controls['NewPassword']">
            <small *ngIf="!changePWForm.controls.NewPassword.valid && !changePWForm.controls.NewPassword.pristine">You need a secure password.</small>
            </div>
            <div class="form-group" >
            <label>Confirm New Password:</label>
            <input type="text" [(ngModel)]="changePWData.ConfirmPassword" [formControl]="changePWForm.controls['ConfirmPassword']">
            </div>
            <div class="form-group">
            <label>Security Question:</label>
            <select #select type="text" [(ngModel)]="selectedSecurityQuestion" [formControl]="changePWForm.controls['SecurityQuestions']" class="select">
                <option *ngFor="let question of securityQuestions" [ngValue]="question">{{question.SecurityQuestionText}}</option>
            </select>
            </div>
            <div class="form-group">
            <label>Security Question Answer: </label>
            <input type="text" [(ngModel)]="securityQuestionAnswer" [formControl]="changePWForm.controls['SecurityQuestionAnswer']">
            </div>
            <div *ngIf="processing">
                    <div class="spinner">
                        <div class="rect1"></div>
                        <div class="rect2"></div>
                        <div class="rect3"></div>
                        <div class="rect4"></div>
                        <div class="rect5"></div>
                    </div>

            </div>
            <button *ngIf="!processing" type="submit" [disabled]="!changePWForm.valid">Change Address</button>
        </form>

【问题讨论】:

    标签: javascript angular validation


    【解决方案1】:

    问题是你有一个嵌套的FormGroup (matchingPassword)。

    因此,您必须使用&lt;div&gt; 来包装这个嵌套 组的控件,例如。

    将您的密码控件(NewPassword 和 ConfirmPassword)包装在一个元素中,如下所示:

    <form [formGroup]="changePWForm" ...>    
      ...    
      <div formGroupName="matchingPassword">
        <!-- you can also use [formGroup] if you want -->
        <!-- Put the content of password controls here -->
      </div>
      ...
    </form>
    

    【讨论】:

      【解决方案2】:

      除了 developer033 所说的问题外,您还缺少formGroupName

      <div formGroupName="matchingPassword">
        <!-- you can also use [formGroup] if you want -->
        <!-- Put the content of password controls here -->
      </div>
      

      .. 我也不太了解自定义验证器,它对我来说不能正常工作。还注意到由于某种原因,验证器在标记表单控件时甚至不会触发:

      [formControl]="changePWForm.controls['NewPassword']"
      

      我真的不能说为什么,但我也更喜欢更“干净”的版本:

      formControlName="NewPassword"
      

      因此更改这些会使自定义验证器触发。

      然后到自定义验证器,这就是我的做法。另请注意,我已将 areEqual: true 更改为 notEqual:true 以更好地描述实际发生的情况,因为当我们返回 null 时,这意味着密码匹配,如果我们返回 null 以外的其他内容,则意味着我们要标记密码不匹配。

      equalPasswords = (control: AbstractControl): {[key: string]: boolean} =>{
        const newPassword = control.get('NewPassword');
        const confirmPassword = control.get('ConfirmPassword');
      
        if (!newPassword || !confirmPassword) {
          return null;
        }
      
        return newPassword.value === confirmPassword.value ? null : { notEqual: true };
      }    
      

      这是一个 DEMO,其中包含您的代码的缩短版本。

      【讨论】:

      • 嗯,我没有提到他的function不正确的事实,因为我认为这只是一个例子,他只是试图修复模板之前的错误。关于 cleaner 版本我同意你的说法,但是我更喜欢在组件文件中创建一个引用并像这样使用[formControl]="myVariableCtrl" :) 这只是一个偏好问题。
      • 是的,这是一个偏好问题,因此我说我更喜欢.. :P 但是,是的,我认为该功能是 OP 使用的功能,所以我只是想同时处理它(阅读:我很无聊):D
      • @developer033 啊,忘了标记你:P
      猜你喜欢
      • 2018-05-28
      • 1970-01-01
      • 2020-04-05
      • 1970-01-01
      • 1970-01-01
      • 2017-09-12
      • 2019-07-04
      • 1970-01-01
      • 2018-12-05
      相关资源
      最近更新 更多