我是Angular中的Reactive Forms的新手。我的表单中有多个复选框数组。当用户单击“全选”按钮时,我需要选中所有复选框。在我的示例中,我想检查所有年龄列表值。当用户单击“全部取消选择”时,我要全部取消选择。我尝试过,但是没有用。
HTML
<form [formGroup]="myForm">
<p>Language</p>
<div *ngFor="let data of languages let i = index">
<input type="checkbox" (change)="onChange(data.name, $event.target.checked)"> {{data.name}}<br>
</div>
<p>Age List</p>
<button (click)="checkAll()">Check all</button>
<button (click)="deselectAll()">Deselect all</button>
<div *ngFor="let data of ages let j = index">
<input type="checkbox" (change)="onAgeChange(data.name, $event.target.checked)"> {{data.name}}<br>
</div>
</form>
<pre>Form values: {{myForm.value | json}}</pre>
应用组件
ages = [{ ageID: 100 ,name: "0 -10 years" }, {ageID: 200 ,name: "10 -20 years" }, {ageID: 300 ,name: "30 -40 years" }, { ageID: 400 ,name: "40 -50 years" }]
languages = [{ langID: 1 ,name: "English" }, {langID: 2 ,name: "Tamil" }, {langID: 3 ,name: "Hindi" }, { langID: 4 ,name: "French" }]
myForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.myForm = this.fb.group({
userage: this.fb.array([]),
userlanguage: this.fb.array([])
});
}
onChange(language: string, isChecked: boolean) {
const languageFormArray = <FormArray>this.myForm.controls.userlanguage;
if (isChecked) {
languageFormArray.push(new FormControl(language));
} else {
let index = languageFormArray .controls.findIndex(x => x.value == language)
languageFormArray .removeAt(index);
}
}
onAgeChange(age : string, isChecked: boolean) {
const ageFormArray = <FormArray>this.myForm.controls.userage;
if (isChecked) {
ageFormArray.push(new FormControl(age));
} else {
let index = ageFormArray.controls.findIndex(x => x.value == age)
ageFormArray.removeAt(index);
}
}
checkAll(){
const languageFormArray = <FormArray>this.myForm.controls.userlanguage;
//console.log(this.myForm.controls['userage'])
this.myForm.controls['userage'].setValue(
this.myForm.controls['userage'].value
.map(value => true)
);
}
这是我到目前为止尝试过的 https://stackblitz.com/edit/angular-butm3h?file=src%2Fapp%2Fapp.component.html
感谢任何人都可以给我支持。
答案 0 :(得分:0)
我会做些不同的事情,而是创建一个FormArray
年龄段的人。然后将它们切换为false
或true
。提交后,我们会过滤以下true
复选框:
ngOnInit() {
getAPIData().subscribe((...) => {
// is ages coming from api? Then change accordingly!
const ages = this.ages.map(x => this.fb.control(false))
this.myForm = this.fb.group({
userage: this.fb.array(ages),
});
})
}
// create a getter for easier access (not necessary)
get ageArr() {
return this.myForm.get('userage') as FormArray;
}
checkAll() {
this.ageArr.controls.map(value => value.setValue(true))
}
deselectAll() {
this.ageArr.controls.map(value => value.setValue(false))
}
在模板中,我们迭代formarray而不是ages
数组。还请记住将type="button"
放在全选按钮上,然后取消选择所有按钮,否则默认情况下它们将被视为type="submit"
。
如果这是异步的,则最好在表单标签上设置一个*ngIf
<form *ngIf="myForm">
<!-- -->
<div formArrayName="userage" *ngFor="let age of ageArr.controls; let i = index">
<input type="checkbox" [formControlName]="i"> {{ages[i].name}}
</div>
</form>
然后,如前所述,只需在提交时过滤true
值:
onSubmit() {
const chosenAges = this.ageArr.value
.map((age, i) => age ? this.ages[i].name : null)
.filter(age => age !== null);
console.log(chosenAges);
}
您的 StackBlitz
答案 1 :(得分:0)
好的,我们需要摆脱事件驱动模式,开始考虑数据驱动模式,这是Angular的优势。
您不想将其包装在def __init__(self, *args, **kwargs):
choices = kwargs.pop("choices")
super(FormAffiliateReport, self).__init__(*args, **kwargs)
self.fields['referrals'].choices = choices
中。所有这些都会导致您尝试提交时产生回发,这与Angular是单页应用程序的观点背道而驰(请注意,在某些情况下,<Form>
是合适的,即验证和仅在提交事件被拦截的情况下。)
我摆脱了您的表单组,并调整了HTML模板以遵循Angular数据绑定所采用的方法。我添加了<Form>
的使用来将您的复选框绑定到基础数据,并为数据模型添加了[(ngModel)]
属性。
请参见the Stackblitz。
模板更改:
isChecked
主要代码更改:
<input type="checkbox" [(ngModel)]="data.isChecked" />
您的数据:
checkAll(){
this.ages.forEach(o => o.isChecked = true);
}
uncheckAll(){
this.ages.forEach(o => o.isChecked = false);
}