接受的答案滥用了一些东西,以不应该的方式使用。使用reactive forms,最好、最简单且可能是正确的方法是使用FormGroup 来保存您的分组复选框并创建一个验证器来检查该组中是否至少有一个(或多个)复选框被选中。
为此,只需在现有的 FormGroup 中创建另一个 FormGroup 并将验证器附加到它:
form = new FormGroup({
// ...more form controls...
myCheckboxGroup: new FormGroup({
myCheckbox1: new FormControl(false),
myCheckbox2: new FormControl(false),
myCheckbox3: new FormControl(false),
}, requireCheckboxesToBeCheckedValidator()),
// ...more form controls...
});
这里是验证器。我这样做是为了让您甚至可以使用它来检查是否至少选中了 X 个复选框,例如requireCheckboxesToBeCheckedValidator(2):
import { FormGroup, ValidatorFn } from '@angular/forms';
export function requireCheckboxesToBeCheckedValidator(minRequired = 1): ValidatorFn {
return function validate (formGroup: FormGroup) {
let checked = 0;
Object.keys(formGroup.controls).forEach(key => {
const control = formGroup.controls[key];
if (control.value === true) {
checked ++;
}
});
if (checked < minRequired) {
return {
requireCheckboxesToBeChecked: true,
};
}
return null;
};
}
不要忘记在您的模板中添加指令“formGroupName”来包装您的复选框。不过不用担心,如果您忘记了,编译器会用错误消息提醒您。然后,您可以像在 FormControl 上一样检查复选框组是否有效:
<ng-container [formGroup]="form">
<!-- ...more form controls... -->
<div class="form-group" formGroupName="myCheckboxGroup">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" formControlName="myCheckbox1" id="myCheckbox1">
<label class="custom-control-label" for="myCheckbox1">Check</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" formControlName="myCheckbox2" id="myCheckbox2">
<label class="custom-control-label" for="myCheckbox2">At least</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" formControlName="myCheckbox3" id="myCheckbox3">
<label class="custom-control-label" for="myCheckbox3">One</label>
</div>
<div class="invalid-feedback" *ngIf="form.controls['myCheckboxGroup'].errors && form.controls['myCheckboxGroup'].errors.requireCheckboxesToBeChecked">At least one checkbox is required to check</div>
</div>
<!-- ...more form controls... -->
</ng-container>
*这个模板是非常静态的。当然,您可以通过使用包含表单数据(FormControl 的键、标签、必需等)的附加数组来动态创建它,并使用 ngFor 自动创建模板。
请不要在接受的答案中滥用隐藏的 FormControl。 FormControl 并不意味着存储 id、标签、帮助文本等数据,甚至没有名称/键。所有这些,以及更多,都应该单独存储,例如通过一个规则的对象数组。 FormControl 只保存一个输入值并提供所有这些很酷的状态和功能。
我创建了一个工作示例,您可以使用:https://stackblitz.com/edit/angular-at-least-one-checkbox-checked