Проверка поперечного поля в Angular2
Я создаю клиентское приложение Angular2. В настоящее время я работаю над компонентами членства и интегрирую компоненты на стороне клиента с MVC6 vNext Identity v3. Я написал пользовательские Angular2 валидаторы паролей следующим образом:
needsCapitalLetter(ctrl: Control): {[s: string]: boolean} {
if(!ctrl.value.match(/[A-Z]/))
return {'needsCapitalLetter': true}
return null;
}
needsLowerLetter(ctrl: Control): {[s: string]: boolean} {
if(!ctrl.value.match(/[a-z]/))
return {'needsLowerLetter': true}
return null;
}
needsNumber(ctrl: Control): {[s: string]: boolean} {
if(!ctrl.value.match(/\d/))
return {'needsNumber': true}
return null;
}
needsSpecialCharacter(ctrl: Control): {[s: string]: boolean} {
if(!ctrl.value.match(/[^a-zA-Z\d]/))
return {'needsSpecialCharacter': true}
return null;
}
Это отлично работает, и я люблю Angular2, но теперь я пытаюсь написать валидатор, который проверяет, что "Confirm Password" равен "Password". Для этого мне нужно иметь возможность проверять одно поле против другого. Я могу легко сделать это на уровне компонентов, и просто проверить размытие, или отправить, или любое количество других способов, но это обходит систему проверки w490 > ngForm. Я очень хотел бы выяснить, как написать Angular2 Validator для поля, которое может проверять значение другого поля, передавая имя другого поля или что-то близкое к этому. Похоже, что это должна быть возможность, поскольку это было бы необходимо в почти любом сложном пользовательском интерфейсе бизнес-приложений.
Ответы
Ответ 1
Вам необходимо назначить валидатор для полной группы форм для его реализации. Что-то вроде этого:
this.form = fb.group({
name: ['', Validators.required],
email: ['', Validators.required]
matchingPassword: fb.group({
password: ['', Validators.required],
confirmPassword: ['', Validators.required]
}, {validator: this.areEqual}) <--------
});
Таким образом, у вас будет доступ ко всем элементам управления группы, а не только к одному... Доступ к этому можно получить, используя свойство controls
группового элемента управления. Последний (не один) напрямую предоставляется при срабатывании проверки. Например:
areEqual(group: ControlGroup) {
var valid = false;
for (name in group.controls) {
var val = group.controls[name].value
(...)
}
if (valid) {
return null;
}
return {
areEqual: true
};
}
См. этот вопрос для получения дополнительной информации:
Ответ 2
Вы также можете использовать специальный проверочный инструмент для сравнения полей.
В вашем html:
<div>
<label>Password</label>
<input type="password" name="password" [ngModel]="user.password"
required #password="ngModel">
<small [hidden]="password.valid || (password.pristine && !f.submitted)">
Password is required
</small>
</div>
<div>
<label>Retype password</label>
<input type="password" name="confirmPassword" [ngModel]="user.confirmPassword"
required validateEqual="password" #confirmPassword="ngModel">
<small [hidden]="confirmPassword.valid || (confirmPassword.pristine && !f.submitted)">
Password mismatch
</small>
</div>
И ваша директива:
import { Directive, forwardRef, Attribute } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
@Directive({
selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
]
})
export class EqualValidator implements Validator {
constructor( @Attribute('validateEqual') public validateEqual: string) {}
validate(c: AbstractControl): { [key: string]: any } {
// self value (e.g. retype password)
let v = c.value;
// control value (e.g. password)
let e = c.root.get(this.validateEqual);
// value not equal
if (e && v !== e.value) return {
validateEqual: false
}
return null;
}
}
Вот полное решение в plunkr:
https://plnkr.co/edit/KgjSTj7VqbWMnRdYZdxM?p=preview
Ответ 3
Я не делал этого сам, но вы могли бы создать ControlGroup
с двумя полями пароля и проверить его. Элементы управления имеют свойство .valueChanges
, которое является наблюдаемым, и вы можете комбинировать их и проверять наличие там равенства.
Виктор Савкин кратко рассказывает об этом конкретном случае на Angular Воздух в этот эпизод