Проверка ввода одного и того же пароля Angular 2/4 - ОШИБКА Не удается найти элемент управления с неопределенным атрибутом имени

Я пытаюсь проверить, что поля пароля и ConfirmPassword совпадают в моей форме, но когда я добавляю проверку, предоставленную другими сообщениями на SO (помимо изменения ControlGroup на FormGroup), я продолжаю получать

ОШИБКА: не удается найти элемент управления с неопределенным атрибутом имени.

НО, когда я не проверяю, используя группу «MatchPassword» ниже, а просто использую синтаксис 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>

person billy_comic    schedule 16.05.2017    source источник


Ответы (2)


Проблема в том, что у вас вложенный FormGroup (matchingPassword).

Таким образом, вы должны заключить элементы управления этой вложенной группы, например, с помощью <div>.

Оберните элементы управления паролем (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>
person developer033    schedule 17.05.2017

Помимо проблемы, указанной 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 };
}    

Вот ДЕМО с сокращенной версией вашего кода.

person AJT82    schedule 17.05.2017
comment
Хм, я не упомянул тот факт, что его функция неверна, потому что я думал, что это просто пример, и он просто пытался исправить ошибку шаблона раньше. Что касается версии чище, я согласен с вашим утверждением, однако я предпочитаю создать ссылку в файле компонента и использовать ее так [formControl]="myVariableCtrl" :) это просто вопрос предпочтения. - person developer033; 17.05.2017
comment
Да, это вопрос предпочтений, поэтому я сказал, что предпочитаю ..: P Но да, я подумал, что это функция, которую использует OP, поэтому я просто подумал о том, чтобы позаботиться об этом в то же время (читайте: я был скучно): D - person AJT82; 17.05.2017
comment
@ developer033 Аа, забыл отметить вас: P - person AJT82; 17.05.2017