我有一个表格,我希望用户编辑他想要收到的杂志订阅。代码如下:
零件:
export class OrderFormComponent {
subscriptions = [
{id: 'weekly', display: 'Weekly newsletter'},
{id: 'monthly', display: 'Monthly newsletter'},
{id: 'quarterly', display: 'Quarterly newsletter'},
];
mySubs = [
this.subscriptions[1]
]
order = new FormGroup({
subs: new FormArray(this.mySubs.map(sub => new FormControl(sub)), Validations.required) //Lost at this part
});
}
模板:
<form [formGroup]="order">
<div formArrayName="subs">
<label>Sign me up for newsletters</label>
<p *ngFor="let s of subscriptions; let i=index">
<input type="checkbox" [value]="s.id" [formControlName]="i" /> {{ s.display }}
</p>
</div>
<div>
<input type="checkbox" formControlName="agree" /> I agree to the terms and conditions.
</div>
{{ order.value | json }}
当我运行应用程序时,会显示三个复选框,但只检查了一个(错误的一个)。被检查的那个有标签,而其他没有。
我在这做错了什么?
好的,我终于明白了。
在我的组件中,我有:
// The order retrieved from the server
subscription = {
schedules: [{id: 'weekly', display: 'Weekly update'}],
}
//The FormGroup element
this.subscriptionForm = new FormGroup({
//Here I fill up a FormArray with some FormControls initialized to the
//currently selected schedules
schedules: new FormArray(this.subscription.schedules.map(schedule => new FormControl(schedule)), Validators.minLength(1))
});
在视图中我有:
<div>
<label>Frequency</label>
<p *ngFor="let schedule of viewData.schedules">
<input type="checkbox"
[checked]="subscription.schedules.includes(schedule)"
(change)="changeSchedules(schedule)"> {{ schedule.display }}
</p>
</div>
这是课堂上的changeSchedules()
方法:
changeSchedules(schedule: any) {
var currentScheduleControls: FormArray = this.subscriptionForm.get('schedules') as FormArray;
var index = currentScheduleControls.value.indexOf(schedule);
if(index > -1) currentScheduleControls.removeAt(index) //If the user currently uses this schedule, remove it.
else currentScheduleControls.push(new FormControl(schedule)); //Otherwise add this schedule.
}
奇迹般有效!表单按预期验证,在表单提交之前无需额外的方法来检索/合并订阅数组。
你在实例化FormControl
时犯了一个错误。不是为所有选项创建FormControl
的新实例,而是只创建一个(通过迭代你的mySub
)。将您的代码更改为此类(未经测试):
order = new FormGroup({
// creating an array of form control with default values
subs: new FormArray(this.subscriptions.map(sub => new FormControl(this.isSelectedSub(sub))), Validations.required)
});
//...
isSelectedSub(sub): boolean {
return this.mySubs.indexOf(sub) >= 0;
}
在发送之前,您可能需要一个功能来将复选框合并到一系列选定的杂志订阅中。