여러 양식 필드에 의존하는 Angular2 유효성 검사기
내 필드가 유효한지 결정하기 위해 여러 값을 사용할 수있는 유효성 검사기를 만들 수 있습니까?
예를 들어 고객이 선호하는 연락 방법이 이메일 인 경우 이메일 필드가 필요합니다.
감사.
예제 코드로 업데이트 됨 ...
import {Component, View} from 'angular2/angular2';
import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms';
@Component({
selector: 'customer-basic',
viewInjector: [FormBuilder]
})
@View({
templateUrl: 'app/components/customerBasic/customerBasic.html',
directives: [formDirectives]
})
export class CustomerBasic {
customerForm: ControlGroup;
constructor(builder: FormBuilder) {
this.customerForm = builder.group({
firstname: [''],
lastname: [''],
validateZip: ['yes'],
zipcode: ['', this.zipCodeValidator]
// I only want to validate using the function below if the validateZip control is set to 'yes'
});
}
zipCodeValidator(control) {
if (!control.value.match(/\d\d\d\d\d(-\d\d\d\d)?/)) {
return { invalidZipCode: true };
}
}
}
다른 사람들이 게시 한 방법을 반복하기 위해 이것이 FormGroup
여러 그룹을 포함하지 않는 유효성 검사기를 만드는 방법 입니다.
이 예에서는 password
및 confirmPassword
필드 의 키 이름을 제공하기 만하면 됩니다.
// Example use of FormBuilder, FormGroups, and FormControls
this.registrationForm = fb.group({
dob: ['', Validators.required],
email: ['', Validators.compose([Validators.required, emailValidator])],
password: ['', Validators.required],
confirmPassword: ['', Validators.required],
firstName: ['', Validators.required],
lastName: ['', Validators.required]
}, {validator: matchingPasswords('password', 'confirmPassword')})
위해서는 Validators
매개 변수를 적용하려면, 그들은을 반환해야 function
와 함께 중 하나 FormGroup
또는 FormControl
매개 변수로. 이 경우 FormGroup
.
function matchingPasswords(passwordKey: string, confirmPasswordKey: string) {
return (group: FormGroup): {[key: string]: any} => {
let password = group.controls[passwordKey];
let confirmPassword = group.controls[confirmPasswordKey];
if (password.value !== confirmPassword.value) {
return {
mismatchedPasswords: true
};
}
}
}
기술적으로는 두 값의 키를 알고 있으면 유효성을 검사 할 수 있었지만 Validators
반환 할 오류와 동일한 이름을 지정하는 것을 선호합니다 . 반환 된 오류의 키 이름을 나타내는 세 번째 매개 변수를 사용하도록 함수를 수정할 수 있습니다.
2016 년 12 월 6 일 업데이트 됨 (v2.2.4)
전체 예 : https://embed.plnkr.co/ukwCXm/
Dave의 대답 은 매우, 매우 도움이되었습니다. 그러나 약간의 수정이 일부 사람들에게 도움이 될 수 있습니다.
Control
필드 에 오류를 추가해야하는 경우 양식 및 유효성 검사기의 실제 구성을 유지할 수 있습니다.
// Example use of FormBuilder, ControlGroups, and Controls
this.registrationForm= fb.group({
dob: ['', Validators.required],
email: ['', Validators.compose([Validators.required, emailValidator])],
password: ['', Validators.required],
confirmPassword: ['', Validators.required],
firstName: ['', Validators.required],
lastName: ['', Validators.required]
}, {validator: matchingPasswords('password', 'confirmPassword')})
에 오류를 설정하는 대신 ControlGroup
실제 필드에서 다음과 같이 설정하십시오.
function matchingPasswords(passwordKey: string, passwordConfirmationKey: string) {
return (group: ControlGroup) => {
let passwordInput = group.controls[passwordKey];
let passwordConfirmationInput = group.controls[passwordConfirmationKey];
if (passwordInput.value !== passwordConfirmationInput.value) {
return passwordConfirmationInput.setErrors({notEquivalent: true})
}
}
}
여러 양식 필드에 대한 유효성 검사기를 구현할 때 각 양식 컨트롤이 업데이트 될 때 유효성 검사기가 다시 평가되는지 확인해야합니다. 대부분의 예제는 이러한 시나리오에 대한 솔루션을 제공하지 않지만 데이터 일관성과 올바른 동작을 위해 매우 중요합니다.
이를 고려한 Angular 2 용 사용자 정의 유효성 검사기 구현을 참조하십시오 : https://gist.github.com/slavafomin/17ded0e723a7d3216fb3d8bf845c2f30 .
내가 사용하고 otherControl.valueChanges.subscribe()
다른 컨트롤의 변화를 수신하고 thisControl.updateValueAndValidity()
다른 제어가 변경 될 때 검증의 또 다른 라운드를 트리거 할 수 있습니다.
향후 참조를 위해 아래 코드를 복사하고 있습니다.
match-other-validator.ts
import {FormControl} from '@angular/forms';
export function matchOtherValidator (otherControlName: string) {
let thisControl: FormControl;
let otherControl: FormControl;
return function matchOtherValidate (control: FormControl) {
if (!control.parent) {
return null;
}
// Initializing the validator.
if (!thisControl) {
thisControl = control;
otherControl = control.parent.get(otherControlName) as FormControl;
if (!otherControl) {
throw new Error('matchOtherValidator(): other control is not found in parent group');
}
otherControl.valueChanges.subscribe(() => {
thisControl.updateValueAndValidity();
});
}
if (!otherControl) {
return null;
}
if (otherControl.value !== thisControl.value) {
return {
matchOther: true
};
}
return null;
}
}
용법
반응 형과 함께 사용하는 방법은 다음과 같습니다.
private constructForm () {
this.form = this.formBuilder.group({
email: ['', [
Validators.required,
Validators.email
]],
password: ['', Validators.required],
repeatPassword: ['', [
Validators.required,
matchOtherValidator('password')
]]
});
}
더 많은 최신 유효성 검사기는 moebius-mlm / ng-validators 에서 찾을 수 있습니다 .
Angular 2 RC.5를 사용하고 있지만 Dave의 유용한 답변을 기반으로 ControlGroup을 찾을 수 없습니다. FormGroup이 대신 작동한다는 것을 알았습니다. 그래서 저는 Dave의 코드에 대해 약간의 업데이트를했고 다른 사람들과 공유 할 것이라고 생각했습니다.
구성 요소 파일에서 FormGroup에 대한 가져 오기를 추가합니다.
import {FormGroup} from "@angular/forms";
양식 컨트롤에 직접 액세스해야하는 경우 입력을 정의합니다.
oldPassword = new FormControl("", Validators.required);
newPassword = new FormControl("", Validators.required);
newPasswordAgain = new FormControl("", Validators.required);
생성자에서 양식을 인스턴스화하십시오.
this.form = fb.group({
"oldPassword": this.oldPassword,
"newPassword": this.newPassword,
"newPasswordAgain": this.newPasswordAgain
}, {validator: this.matchingPasswords('newPassword', 'newPasswordAgain')});
클래스에 matchingPasswords 함수를 추가합니다.
matchingPasswords(passwordKey: string, passwordConfirmationKey: string) {
return (group: FormGroup) => {
let passwordInput = group.controls[passwordKey];
let passwordConfirmationInput = group.controls[passwordConfirmationKey];
if (passwordInput.value !== passwordConfirmationInput.value) {
return passwordConfirmationInput.setErrors({notEquivalent: true})
}
}
}
RC.5를 사용하는 사람들에게 도움이되기를 바랍니다. 아직 RC.6에서 테스트하지 않았습니다.
정확히 정확하지 않기 때문에 matthewdaniel의 대답을 확장합니다. 다음은 유효성 검사기를 .NET Framework에 올바르게 할당하는 방법을 보여주는 예제 코드입니다 ControlGroup
.
import {Component} from angular2/core
import {FormBuilder, Control, ControlGroup, Validators} from 'angular2/common'
@Component({
selector: 'my-app',
template: `
<form [ngFormModel]="form">
<label for="name">Name:</label>
<input id="name" type="text" ngControl="name">
<br>
<label for="email">Email:</label>
<input id="email" type="email" ngControl="email">
<br>
<div ngControlGroup="matchingPassword">
<label for="password">Password:</label>
<input id="password" type="password" ngControl="password">
<br>
<label for="confirmPassword">Confirm Password:</label>
<input id="confirmPassword" type="password" ngControl="confirmPassword">
</div>
</form>
<p>Valid?: {{form.valid}}</p>
<pre>{{form.value | json}}</pre>
`
})
export class App {
form: ControlGroup
constructor(fb: FormBuilder) {
this.form = fb.group({
name: ['', Validators.required],
email: ['', Validators.required]
matchingPassword: fb.group({
password: ['', Validators.required],
confirmPassword: ['', Validators.required]
}, {validator: this.areEqual})
});
}
areEqual(group: ControlGroup) {
let val;
let valid = true;
for (name in group.controls) {
if (val === undefined) {
val = group.controls[name].value
} else {
if (val !== group.controls[name].value) {
valid = false;
break;
}
}
}
if (valid) {
return null;
}
return {
areEqual: true
};
}
}
다음은 작동하는 예입니다. http://plnkr.co/edit/Zcbg2T3tOxYmhxs7vaAm?p=preview
각도 소스를 많이 파고 있지만 더 나은 방법을 찾았습니다.
constructor(...) {
this.formGroup = builder.group({
first_name: ['', Validators.required],
matching_password: builder.group({
password: ['', Validators.required],
confirm: ['', Validators.required]
}, this.matchPassword)
});
// expose easy access to passworGroup to html
this.passwordGroup = this.formGroup.controls.matching_password;
}
matchPassword(group): any {
let password = group.controls.password;
let confirm = group.controls.confirm;
// Don't kick in until user touches both fields
if (password.pristine || confirm.pristine) {
return null;
}
// Mark group as touched so we can add invalid class easily
group.markAsTouched();
if (password.value === confirm.value) {
return null;
}
return {
isValid: false
};
}
비밀번호 그룹의 HTML 부분
<div ng-control-group="matching_password" [class.invalid]="passwordGroup.touched && !passwordGroup.valid">
<div *ng-if="passwordGroup.touched && !passwordGroup.valid">Passwords must match.</div>
<div class="form-field">
<label>Password</label>
<input type="password" ng-control="password" placeholder="Your password" />
</div>
<div class="form-field">
<label>Password Confirmation</label>
<input type="password" ng-control="confirm" placeholder="Password Confirmation" />
</div>
</div>
여기에 전체 또는 하위에 의존하지 않고 ControlGroup
각각에 직접 연결되는 또 다른 옵션이 있습니다 Control
.
내가 가진 문제는 서로 의존하는 컨트롤이 계층 적으로 함께 있지 않아서 ControlGroup
. 또한 내 CSS는 각 컨트롤이 기존 앵귤러 클래스를 활용하여 오류 스타일을 표시할지 여부를 결정하도록 설정되었으며, 컨트롤 별 유효성 검사 대신 그룹 유효성 검사를 처리 할 때 더 복잡했습니다. 유효성 검사가 각 개별 컨트롤이 아닌 컨트롤 그룹에 연결되어 있기 때문에 단일 컨트롤이 유효한지 확인하는 것은 불가능했습니다.
제 경우에는 다른 필드가 필요한지 여부를 결정하기 위해 선택 상자의 값을 원했습니다.
이것은 컴포넌트에서 Form Builder를 사용하여 빌드됩니다. 선택 모델의 경우 요청 개체의 값에 직접 바인딩하는 대신 컨트롤에 대한 "변경시"이벤트를 처리 할 수있는 함수를 가져 오거나 설정하도록 바인딩했습니다. 그런 다음 선택 컨트롤 새 값에 따라 다른 컨트롤에 대한 유효성 검사를 수동으로 설정할 수 있습니다.
다음은 관련 뷰 부분입니다.
<select [ngFormControl]="form.controls.employee" [(ngModel)]="employeeModel">
<option value="" selected></option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
...
<input [ngFormControl]="form.controls.employeeID" type="text" maxlength="255" [(ngModel)]="request.empID" />
관련 구성 요소 부분 :
export class RequestComponent {
form: ControlGroup;
request: RequestItem;
constructor(private fb: FormBuilder) {
this.form = fb.group({
employee: new Control("", Validators.required),
empID: new Control("", Validators.compose([Validators.pattern("[0-9]{7}"]))
});
get employeeModel() {
return this.request.isEmployee;
}
set employeeModel(value) {
this.request.isEmployee = value;
if (value === "Yes") {
this.form.controls["empID"].validator = Validators.compose([Validators.pattern("[0-9]{7}"), Validators.required]);
this.form.controls["empID"].updateValueAndValidity();
}
else {
this.form.controls["empID"].validator = Validators.compose([Validators.pattern("[0-9]{7}")]);
this.form.controls["empID"].updateValueAndValidity();
}
}
}
제 경우에는 항상 패턴 유효성 검사가 컨트롤에 연결되어 있으므로 validator
항상 무언가로 설정되어 있지만 validator
컨트롤에 연결된 유효성 검사가 없으면을 null로 설정할 수 있다고 생각합니다 .
업데이트 : 모델 변경을 캡처 (ngModelChange)=changeFunctionName($event)
하거나 제어 값 변경을 사용하여 구독하는 다른 방법이 있습니다.this.form.controls["employee"].valueChanges.subscribe(data => ...))
나는이 대답의 대부분을 시도했지만 그들 중 어느 것도 나를 위해 일하지 않았습니다. 여기에서 작동하는 예제를 찾았습니다 https://scotch.io/@ibrahimalsurkhi/match-password-validation-with-angular-2
이것도 찾고 equalTo
있었고 ng2-validation 패키지 ( https://www.npmjs.com/package/ng2-validation )에서 사용했습니다.
다음은 예입니다. 템플릿 기반 :
<input type="password" ngModel name="password" #password="ngModel" required/>
<p *ngIf="password.errors?.required">required error</p>
<input type="password" ngModel name="certainPassword" #certainPassword="ngModel" [equalTo]="password"/>
<p *ngIf="certainPassword.errors?.equalTo">equalTo error</p>
모델 구동 :
let password = new FormControl('', Validators.required);
let certainPassword = new FormControl('', CustomValidators.equalTo(password));
this.form = new FormGroup({
password: password,
certainPassword: certainPassword
});
주형:
<form [formGroup]="form">
<input type="password" formControlName="password"/>
<p *ngIf="form.controls.password.errors?.required">required error</p>
<input type="password" formControlName="certainPassword"/>
<p *ngIf="form.controls.certainPassword.errors?.equalTo">equalTo error</p>
</form>
다음은 한 필드의 연령이 다른 필드의 연령보다 크거나 같은지 확인하는 데 사용한 버전입니다. 양식 그룹도 사용하고 있으므로 group.get
대신 기능을 사용합니다.group.controls[]
import { FormGroup } from '@angular/forms';
export function greaterThanOrEqualTo(sourceKey: string, targetKey: string) {
return (group: FormGroup) => {
let sourceInput = group.get(sourceKey);
let targetInput = group.get(targetKey);
console.log(sourceInput);
console.log(targetInput);
if (targetInput.value < sourceInput.value) {
return targetInput.setErrors({ notGreaterThanOrEqualTo: true })
}
}
}
그리고 구성 요소에서 :
this.form = this._fb.group({
clientDetails: this._fb.group({
currentAge: ['', [Validators.required, Validators.pattern('^((1[89])|([2-9][0-9])|100)$')]],
expectedRetirementAge: ['', [Validators.required]]
}),
},
{
validator: greaterThanOrEqualTo('clientDetails.currentAge', 'clientDetails.expectedRetirementAge')
});
현재로서는 가장 좋은 방법은 컨트롤을 보유 할 폼 그룹을 만드는 것입니다. 컨트롤을 인스턴스화 할 때 함수의 유효성을 검사합니다. 예:
this.password = new Control('', Validators.required);
let x = this.password;
this.confirm = new Control('', function(c: Control){
if(typeof c.value === 'undefined' || c.value == "") return {required: "password required"};
if(c.value !== x.value)
return {error: "password mismatch"};
return null;
});
나는 이것이 실행중인 angularjs2의 버전에 크게 의존한다는 것을 알고 있습니다. 이것은 2.0.0-alpha.46에 대해 테스트되었습니다.
사용자 지정 유효성 검사기 (가장 좋은 방법 일 수 있음)를 작성하는 것과 같은 더 나은 제안이 있다면 환영합니다.
편집하다
ControlGroup을 사용하고 해당 그룹을 전체적으로 확인할 수도 있습니다.
this.formGroup = new ControlGroup({}, function(c: ControlGroup){
var pass: Control = <Control>c.controls["password"];
var conf: Control = <Control>c.controls["confirm"];
pass.setErrors(null, true);
if(pass.value != null && pass.value != ""){
if(conf.value != pass.value){
pass.setErrors({error: "invalid"}, true);
return {error: "error"};
}
}
return null;
});
도메인에 따라 메시지를 편집하십시오.
Louis Cruz의 답변 은 저에게 매우 도움이되었습니다.
완료하려면 else에 setErrors reset을 추가하십시오. return passwordConfirmationInput.setErrors (null);
그리고 모두 잘 작동합니다!
감사합니다,
문안 인사,
TGA
나는 도서관을 사용하는 것이 좋습니다 ng-form-rules
. 구성 요소에서 분리 된 유효성 검사 논리를 사용하여 모든 다른 종류의 양식을 생성하고 양식의 다른 영역의 값 변경에 따라 달라질 수있는 멋진 라이브러리입니다. 그들은 그것의 기능을 보여주는 훌륭한 문서 , 예제 및 비디오를 가지고 있습니다 . 이와 같은 유효성 검사를 수행하려는 작업은 간단합니다.
README 에서 높은 수준의 정보와 기본 예를 확인할 수 있습니다 .
Angular 4 암호 일치 유효성 검사 규칙.
오류 제어 필드가 필요한 경우 할 수 있습니다.
createForm() {
this.ngForm = this.fb.group({
'first_name': ["", Validators.required ],
'last_name' : ["", Validators.compose([Validators.required, Validators.minLength(3)]) ],
'status' : ['active', Validators.compose([Validators.required])],
'phone':[null],
'gender':['male'],
'address':[''],
'email':['', Validators.compose([
Validators.required,
Validators.email])],
'password':['', Validators.compose([Validators.required])],
'confirm_password':['', Validators.compose([Validators.required])]
}, {validator: this.matchingPassword('password', 'confirm_password')});
}
그런 다음이 메서드를 constructor
Like 메서드에서 선언해야합니다 .
constructor(
private fb: FormBuilder
) {
this.createForm();
}
ControlGroup에 오류를 설정하는 대신 실제 필드에서 다음과 같이 설정하십시오.
matchingPassword(passwordKey: string, confirmPasswordKey: string) {
return (group: FormGroup): {[key: string]: any} => {
let password = group.controls[passwordKey];
let confirm_password = group.controls[confirmPasswordKey];
if (password.value !== confirm_password.value) {
return {
mismatchedPasswords: true
};
}
}
}
비밀번호 그룹의 HTML 부분
<form [formGroup]="ngForm" (ngSubmit)="ngSubmit()">
<div class="form-group">
<label class="control-label" for="inputBasicPassword"> Password <span class="text-danger">*</span></label>
<input type="password" class="form-control" formControlName="password" placeholder="Password" name="password" required>
<div class="alert text-danger" *ngIf="!ngForm.controls['password'].valid && ngForm.controls['password'].touched">This Field is Required.</div>
</div>
{{ngForm.value.password | json}}
<div class="form-group">
<label class="control-label" for="inputBasicPassword">Confirm Password <span class="text-danger">*</span></label>
<input type="password" class="form-control" name="confirm_password" formControlName="confirm_password" placeholder="Confirm Password" match-password="password">
<div class='alert text-danger' *ngIf="ngForm.controls.confirm_password.touched && ngForm.hasError('mismatchedPasswords')">
Passwords doesn't match.
</div>
</div>
<button type="submit" [disabled]="!ngForm.valid" class="btn btn-primary ladda-button" data-plugin="ladda" data-style="expand-left" disabled="disabled"><span class="ladda-label">
<i class="fa fa-save"></i> Create an account
<span class="ladda-spinner"></span><div class="ladda-progress" style="width: 0px;"></div>
</span><span class="ladda-spinner"></span></button>
</form>
참고 URL : https://stackoverflow.com/questions/31788681/angular2-validator-which-relies-on-multiple-form-fields
'Programing' 카테고리의 다른 글
초보자가주의해야 할 Ruby Gotchas는 무엇입니까? (0) | 2020.08.09 |
---|---|
목록에 목록에있는 항목이있는 linq (0) | 2020.08.09 |
JavaScript를 사용하여 HTML의 CSS 배경색을 설정하는 방법 (0) | 2020.08.09 |
SQLite 재설정 기본 키 필드 (0) | 2020.08.09 |
Windows 용 ActivePerl 또는 Strawberry Perl을 선택해야합니까? (0) | 2020.08.08 |