angular - 如何仅在使用 FormGroup 选择其中之一时才需要复选框
问题描述
FormGroup
我在 Angular 4 中使用和进行自定义验证有一些问题FormControl
。我有一个带有多个复选框的页面,在这个例子中是 6 个。其中三个是一直需要的,另外三个操作系统只有在选择其中一两个时才需要。如果没有选择它们,您可以通过验证。
我在 ngOnInit 方法中初始化我的 FormGroup,它看起来像这样
ngOnInit() {
let statements = new FormGroup({});
for (let i = 0; i < this.characters.length; i++) {
const element = this.characters[i];
statements.addControl(element.surname, new FormControl(false, CustomValidator.required));
}
statements.addControl(this.firstPerson.surname, new FormControl(false, CustomValidator.requiredPredicate(
//here I have problem to write predicate which check if thirdPerson or secondPerson checbox was selected
));
statements.addControl(this.secondPerson.surname, new FormControl(false, CustomValidator.requiredPredicate(
//here I have problem to write predicate which check if firstPerson or third checbox was selected
));
statements.addControl(this.thirdPerson.surname, new FormControl(false, CustomValidator.requiredPredicate(
//here I have problem to write predicate which check if firstPerson or secondPerson checbox was selected
));
this.fullData = new FormGroup({
//here I have more than statemets, thats why I have fullData
statements: statements
});
}
这里的 for 循环用于填充所有需要的 checbkox。但我认为我不能为最后三个做这件事,我需要检查是否选择了其他两个。在谓词内部我不知道,如何检查是否选择了其他两个 FormControls(checkboxes)。
这个组件的视图看起来像这样
<form [formGroup]="fullData">
<div formGroupName="statements">
<p>All of these 3 are required</p>
<div *ngFor="let character of characters">
<custom-checkbox
[controlName]="character.surname"
[formGroup]="fullData.get('statements')"
[id]="character.name"
[label]="character.name + ' ' + character.surname">
</custom-checkbox>
</div>
<br />
<br />
<p>Only required when one of them is clicked</p>
<custom-checkbox
[controlName]="firstPerson.surname"
[formGroup]="fullData.get('statements')"
[id]="firstPerson.name"
[label]="firstPerson.name + ' ' + firstPerson.surname">
</custom-checkbox>
<custom-checkbox
[controlName]="secondPerson.surname"
[formGroup]="fullData.get('statements')"
[id]="secondPerson.name"
[label]="secondPerson.name + ' ' + secondPerson.surname">
</custom-checkbox>
<custom-checkbox
[controlName]="thirdPerson.surname"
[formGroup]="fullData.get('statements')"
[id]="thirdPerson.name"
[label]="thirdPerson.name + ' ' + thirdPerson.surname">
</custom-checkbox>
<button type="button" (click)="onSubmit(fullData)"> Submit </button>
</div>
</form>
我在这里使用自定义 checbkox,因为我想在更多地方使用它并扩展它。CustomValidation 类是这样的。
export interface ValidationError {
[msg:string] : boolean;
}
export class CustomValidator {
static required(control: any): ValidationError {
if(control.value && (control.value.length === undefined || control.value.length >0)) {
return null;
}
return {"VALIDATION.REQUIRED": false};
}
static requiredPredicate(predicate: any): ValidatorFn {
return function(control: any){
const value = predicate();
if(value){
return CustomValidator.required(control);
}
return null;
}
}
}
知道我该怎么做吗?
CustomChecbkox 代码:
export class CustomCheckboxComponent implements OnInit, OnDestroy {
@Input('label') label: string;óó
@Input('controlName') controlName: string;
@Input('formGroup') formGroup: FormGroup;
@Input('id') id: string;
@ViewChild('inputField') inputField: any;
@ViewChild('surroundingDiv') surroundingDiv: any;
isValid: boolean = true;
fieldUpdated: boolean = false;
shouldDisplayError: boolean = false;
displayError: boolean = false;
constructor(public cd: ChangeDetectorRef) {
}
ngOnDestroy(): void {
}
fieldChanged(value) {
if (!this.fieldUpdated) {
this.fieldUpdated = true;
this.validateField(value);
}
}
validateField(value): boolean {
if (!this.fieldUpdated) {
return true;
}
this.isValid = this.formGroup.get(this.controlName).errors ? false : true;
if ((this.fieldUpdated) && !this.shouldDisplayError) {
this.shouldDisplayError = true;
}
this.displayError = !this.isValid && this.shouldDisplayError;
return !this.displayError;
}
ngOnInit() {
}
}
和 html
<div class="custom-checkbox"
[formGroup]="formGroup"
#surroundingDiv
[ngClass]="{'custom_validation' : displayError}">
<label class="mdl-checkbox mdl-checkbox--pink mdl-js-checkbox mdl-js-ripple-effect"
for="{{id}}">
<input class="mdl-checkbox__input"
type="checkbox"
id="{{id}}"
formControlName="{{controlName}}"
(change)="fieldChanged($event.target.value)"
#inputField
>{{ label }}
</label>
<div class="custom-validation__error" *ngIf="displayError" style="padding-left: 24px;">
<span *ngFor="let error of formGroup.get(controlName).errors "
>{{error}}</span>
</div>
</div>
解决方案
推荐阅读
- solr - 来自父实体的 Solr 变量未在子实体中设置
- android - 我无法从 sharedpreferences 中删除项目
- python - 将自定义损失函数输出 y test 和 y pred 转换为 numpy 数组
- mysql - max_user_connections Wordpress mysql错误
- php - 文件未作为 .zip 保存在数据库中
- mongodb - Rocket.Chat Meteor 服务器:发布消息后调用方法?
- reactjs - 未能将 React 渲染道具组件重构为 2 个组件
- typescript - 打字稿:“关注”条件类型
- mpi - 使用 mpirun 执行我的程序会大大降低性能
- vba - 将 PreviousControl 属性与嵌套的子窗体和控件一起使用