Angular 2:将验证器添加到 ngModelGroup
Angular 2: Add validators to ngModelGroup
我正在使用 ngModelGroup
指令将多个表单输入组合在一起。
在文档中 (https://angular.io/docs/ts/latest/api/forms/index/NgModelGroup-directive.html) 我读到有一个 validators: any[]
属性.
这是否意味着我可以添加一个仅验证 ngModelGroup
的自定义验证器函数?如果可以,我该如何使用它?
那太棒了,因为我想检查是否至少选中了 ngModelGroup
中的一个复选框。我不能使用 required
,因为那意味着 all 复选框是必需的。我在文档中找不到任何相关信息,还是我找错地方了?
看起来您的模型组中的每个控件都应该有自己的验证器。完成此操作后,您可能可以通过验证器数组访问每个验证器。所以将 required 属性添加到需要的输入中
这完全可以通过 ngModelGroup
和自定义指令进行验证。理解为什么这样做的关键是 ngModelGroup
Creates and binds a FormGroup instance to a DOM element.
首先,我们将构建我们的指令,它是非常样板的,没有什么特别的:
@Directive({
selector: '[hasRequiredCheckboxInGroup]',
providers: [{provide: NG_VALIDATORS, useExisting: HasRequiredCheckBoxInGroup, multi: true}]
})
export class HasRequiredCheckBoxInGroup implements Validator, OnChanges {
private valFn = Validators.nullValidator;
constructor() {
this.valFn = validateRequiredCheckboxInGroup();
}
validate(control: AbstractControl): {[key: string]: any} {
return this.valFn(control);
}
}
我们的验证函数是我们获取 ngModelGroup
创建 FormGroup
并应用它的关键知识的地方:
function validateRequiredCheckboxInGroup() : ValidatorFn {
return (group) => { //take the group we declare in the template as a parameter
let isValid = false; //default to invalid for this case
if(group) {
for(let ctrl in group.controls) {
if(group.controls[ctrl].value && typeof group.controls[ctrl].value === 'boolean') { // including a radio button set might blow this up, but hey, let's be careful with the directives
isValid = group.controls[ctrl].value;
}
}
}
if(isValid) {
return null;
} else {
return { checkboxRequired: true };
}
}
}
最后,在我们的模块中包含并声明指令后,我们 return 到模板(需要采用一种形式):
<form #f="ngForm">
<div ngModelGroup="checkboxes" #chks="ngModelGroup" hasRequiredCheckboxInGroup>
<input type="checkbox" name="chk1" [(ngModel)]="checks['1']"/>
<input type="checkbox" name="chk2" [(ngModel)]="checks['2']"/>
</div>
<div>
{{chks.valid}}
</div>
</form>
这里有一个 plunker,所有这些都可以玩:
http://plnkr.co/edit/AXWGn5XwRo60fkqGBU3V?p=preview
感谢大家帮助我!我接受了 Silentsod 的回答,因为它很有帮助。
我的最终解决方案是使用 FormBuilder
.
简单地构建表单
在我的组件中,创建表单并向其添加验证器函数:
ngOnInit(): void {
// Validator function:
let validateMemberList = (group: FormGroup) => {
let checked = Object.keys(group.controls).reduce((count, key: string) => {
return count + (group.controls[key].value ? 1 : 0);
}, 0);
return checked === 0 ? {'minchecked': 1} : null;
};
this.jobForm = this.formBuilder.group({
jobTitle: ['', Validators.required],
// more inputs...
members: this.formBuilder.group({}, {
// The 2nd argument is an object with a validator property:
validator: validateMemberList
}),
supportMembers: this.formBuilder.group({}, {
validator: validateMemberList
})
});
然后在我的模板中:
<form [formGroup]="jobForm">
<ul formGroupName="members">
<li *ngFor="let user of teamMembers.members">
<label class="e-label">
<input class="e-input" type="checkbox" [formControlName]="user.$key">
<user-badge [user]="user"></user-badge>
</label>
</li>
</ul>
...
这会验证表单,允许我显示错误并禁用提交按钮。
感谢大家的帮助!
我正在使用 ngModelGroup
指令将多个表单输入组合在一起。
在文档中 (https://angular.io/docs/ts/latest/api/forms/index/NgModelGroup-directive.html) 我读到有一个 validators: any[]
属性.
这是否意味着我可以添加一个仅验证 ngModelGroup
的自定义验证器函数?如果可以,我该如何使用它?
那太棒了,因为我想检查是否至少选中了 ngModelGroup
中的一个复选框。我不能使用 required
,因为那意味着 all 复选框是必需的。我在文档中找不到任何相关信息,还是我找错地方了?
看起来您的模型组中的每个控件都应该有自己的验证器。完成此操作后,您可能可以通过验证器数组访问每个验证器。所以将 required 属性添加到需要的输入中
这完全可以通过 ngModelGroup
和自定义指令进行验证。理解为什么这样做的关键是 ngModelGroup
Creates and binds a FormGroup instance to a DOM element.
首先,我们将构建我们的指令,它是非常样板的,没有什么特别的:
@Directive({
selector: '[hasRequiredCheckboxInGroup]',
providers: [{provide: NG_VALIDATORS, useExisting: HasRequiredCheckBoxInGroup, multi: true}]
})
export class HasRequiredCheckBoxInGroup implements Validator, OnChanges {
private valFn = Validators.nullValidator;
constructor() {
this.valFn = validateRequiredCheckboxInGroup();
}
validate(control: AbstractControl): {[key: string]: any} {
return this.valFn(control);
}
}
我们的验证函数是我们获取 ngModelGroup
创建 FormGroup
并应用它的关键知识的地方:
function validateRequiredCheckboxInGroup() : ValidatorFn {
return (group) => { //take the group we declare in the template as a parameter
let isValid = false; //default to invalid for this case
if(group) {
for(let ctrl in group.controls) {
if(group.controls[ctrl].value && typeof group.controls[ctrl].value === 'boolean') { // including a radio button set might blow this up, but hey, let's be careful with the directives
isValid = group.controls[ctrl].value;
}
}
}
if(isValid) {
return null;
} else {
return { checkboxRequired: true };
}
}
}
最后,在我们的模块中包含并声明指令后,我们 return 到模板(需要采用一种形式):
<form #f="ngForm">
<div ngModelGroup="checkboxes" #chks="ngModelGroup" hasRequiredCheckboxInGroup>
<input type="checkbox" name="chk1" [(ngModel)]="checks['1']"/>
<input type="checkbox" name="chk2" [(ngModel)]="checks['2']"/>
</div>
<div>
{{chks.valid}}
</div>
</form>
这里有一个 plunker,所有这些都可以玩: http://plnkr.co/edit/AXWGn5XwRo60fkqGBU3V?p=preview
感谢大家帮助我!我接受了 Silentsod 的回答,因为它很有帮助。
我的最终解决方案是使用 FormBuilder
.
在我的组件中,创建表单并向其添加验证器函数:
ngOnInit(): void {
// Validator function:
let validateMemberList = (group: FormGroup) => {
let checked = Object.keys(group.controls).reduce((count, key: string) => {
return count + (group.controls[key].value ? 1 : 0);
}, 0);
return checked === 0 ? {'minchecked': 1} : null;
};
this.jobForm = this.formBuilder.group({
jobTitle: ['', Validators.required],
// more inputs...
members: this.formBuilder.group({}, {
// The 2nd argument is an object with a validator property:
validator: validateMemberList
}),
supportMembers: this.formBuilder.group({}, {
validator: validateMemberList
})
});
然后在我的模板中:
<form [formGroup]="jobForm">
<ul formGroupName="members">
<li *ngFor="let user of teamMembers.members">
<label class="e-label">
<input class="e-input" type="checkbox" [formControlName]="user.$key">
<user-badge [user]="user"></user-badge>
</label>
</li>
</ul>
...
这会验证表单,允许我显示错误并禁用提交按钮。
感谢大家的帮助!