嵌套 angular 反应形式和查找控件时出错
Nested angular reactive form and error with finding control
我想在 Angular 中创建一个可以提交对象数组的表单。
结果我想得到这样一个Json:
order = {
selectedDays: [{
meals: [
{name: 'breakfast',
selected: false},
{name: 'dinner',
selected: false},
{name: 'supper',
selected: false}
],
selectedDay: "10/01/2018"
}
]}
但是,我在查找控件时遇到了一些问题。我收到此错误:
Error: Cannot find control with path: 'selectedDays -> 0 -> meals -> breakfast'
这是我的代码:
HTML:
<div class="" [formGroup]="form">
<button (click)="addNewDay()">Dodaj nowe zamówienie</button><br><br>
<div class="row" formArrayName="selectedDays">
<div *ngFor="let day of form.get('selectedDays').controls; let i=index">
<fieldset>
<legend><h3>Chosen day {{i+1}}: </h3></legend>
<div [formGroupName]="i">
<div class="col-md-3">
<h5>Choose date</h5>
<mat-form-field >
<input matInput formControlName="selectedDate" [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</div>
<div class="col-md-3" formArrayName="meals">
<div><mat-checkbox formControlName="breakfast"> breakfast </mat-checkbox> </div>
<div><mat-checkbox formControlName="dinner"> dinner </mat-checkbox> </div>
<div><mat-checkbox formControlName="supper"> supper </mat-checkbox> </div>
</div>
</div>
</fieldset>
</div>
</div>
<button click="submit()">Send order</button>
<pre>Form values: {{form.value | json}}</pre>
打字稿:
export class OrderFormComponent implements OnInit {
public form: FormGroup;
public availableMeals: string[] = [
"breakfast", "dinner", "supper"
];
order = {
selectedDays: [
{
meals: [
{name: 'breakfast',
selected: false},
{name: 'dinner',
selected: false},
{name: 'supper',
selected: false}
],
selectedDay: "10/01/2018"
}
]
}
constructor(private orderService: OrderService,
private formBuilder: FormBuilder) {
this.form = this.formBuilder.group({
selectedDays: this.formBuilder.array([])
})
this.setSelectedDays();
}
addNewDay() {
let control = <FormArray>this.form.controls.selectedDays;
control.push(
this.formBuilder.group({
meals: this.formBuilder.array([]),
selectedDate: new FormControl((new Date()))
})
)
}
setSelectedDays() {
let control = <FormArray>this.form.controls.selectedDays;
this.order.selectedDays.forEach(x => {
control.push(this.formBuilder.group({
meals: this.mapToCheckboxArrayGroup(this.availableMeals),
selectedDate: x.selectedDay
}))
})
}
submit() {
this.orderService.sendOrder(this.form.value).subscribe(() => {
console.log("Order added");
},
err => {
console.log('error occurred: ' + err.message);
}
);
}
private mapToCheckboxArrayGroup(data: string[]): FormArray {
return this.formBuilder.array(data.map((meal) => {
return this.formBuilder.group({
name: meal,
selected: false
});
}));
}
}
我的Day.ts对象:
export interface Day {
meals: [
{name: 'breakfast',
selected: boolean},
{name: 'dinner',
selected: boolean},
{name: 'supper',
selected: boolean}
]
selectedDay: string;
}
可能我遗漏了什么,但我无法自己解决 - 我是 Angular 的新手。我将不胜感激!
所以制作后my own version of this。有几件事要讨论。首先是您在以下代码中使用 formControlName
<div class="col-md-3" formArrayName="meals">
<div><mat-checkbox formControlName="breakfast"> breakfast </mat-checkbox> </div>
<div><mat-checkbox formControlName="dinner"> dinner </mat-checkbox> </div>
<div><mat-checkbox formControlName="supper"> supper </mat-checkbox> </div>
</div>
问题是您的控件没有名称。如果您在控制台中拉出表单,您会注意到它变为 FormGroup -> Controls -> Meals -> Controls -> 0-3
。您必须再次遍历它们并尝试从对象本身中提取名称。 事实证明这真的很难,至少对我自己来说是这样。相反,您可能想像为 selectedDays
所做的那样将变量分配给数组的索引,然后 使用迭代器 访问 meals
属性 order.selectedDays[i]
.
如果你这样做,你最终会从硬编码各种复选框切换到选择一个 *ngFor
来自动提取信息并附加 selected
属性 in order.selectedDays[i].meals[m]
通过 [(ngModel)]
.
到复选框
查看我链接到的 StackBlitz 示例,我知道它在设计方面看起来完全不同,但正在使用我提到的方法。您有兴趣查看提到的迭代方法的控件是 order-form
控件,请注意,在该控件中我使用 get meals(): FormArray { return this.form.get('meals') as FormArray; }
这允许我使用 [formControlName] = "i"
.
我想在 Angular 中创建一个可以提交对象数组的表单。
结果我想得到这样一个Json:
order = {
selectedDays: [{
meals: [
{name: 'breakfast',
selected: false},
{name: 'dinner',
selected: false},
{name: 'supper',
selected: false}
],
selectedDay: "10/01/2018"
}
]}
但是,我在查找控件时遇到了一些问题。我收到此错误:
Error: Cannot find control with path: 'selectedDays -> 0 -> meals -> breakfast'
这是我的代码:
HTML:
<div class="" [formGroup]="form">
<button (click)="addNewDay()">Dodaj nowe zamówienie</button><br><br>
<div class="row" formArrayName="selectedDays">
<div *ngFor="let day of form.get('selectedDays').controls; let i=index">
<fieldset>
<legend><h3>Chosen day {{i+1}}: </h3></legend>
<div [formGroupName]="i">
<div class="col-md-3">
<h5>Choose date</h5>
<mat-form-field >
<input matInput formControlName="selectedDate" [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</div>
<div class="col-md-3" formArrayName="meals">
<div><mat-checkbox formControlName="breakfast"> breakfast </mat-checkbox> </div>
<div><mat-checkbox formControlName="dinner"> dinner </mat-checkbox> </div>
<div><mat-checkbox formControlName="supper"> supper </mat-checkbox> </div>
</div>
</div>
</fieldset>
</div>
</div>
<button click="submit()">Send order</button>
<pre>Form values: {{form.value | json}}</pre>
打字稿:
export class OrderFormComponent implements OnInit {
public form: FormGroup;
public availableMeals: string[] = [
"breakfast", "dinner", "supper"
];
order = {
selectedDays: [
{
meals: [
{name: 'breakfast',
selected: false},
{name: 'dinner',
selected: false},
{name: 'supper',
selected: false}
],
selectedDay: "10/01/2018"
}
]
}
constructor(private orderService: OrderService,
private formBuilder: FormBuilder) {
this.form = this.formBuilder.group({
selectedDays: this.formBuilder.array([])
})
this.setSelectedDays();
}
addNewDay() {
let control = <FormArray>this.form.controls.selectedDays;
control.push(
this.formBuilder.group({
meals: this.formBuilder.array([]),
selectedDate: new FormControl((new Date()))
})
)
}
setSelectedDays() {
let control = <FormArray>this.form.controls.selectedDays;
this.order.selectedDays.forEach(x => {
control.push(this.formBuilder.group({
meals: this.mapToCheckboxArrayGroup(this.availableMeals),
selectedDate: x.selectedDay
}))
})
}
submit() {
this.orderService.sendOrder(this.form.value).subscribe(() => {
console.log("Order added");
},
err => {
console.log('error occurred: ' + err.message);
}
);
}
private mapToCheckboxArrayGroup(data: string[]): FormArray {
return this.formBuilder.array(data.map((meal) => {
return this.formBuilder.group({
name: meal,
selected: false
});
}));
}
}
我的Day.ts对象:
export interface Day {
meals: [
{name: 'breakfast',
selected: boolean},
{name: 'dinner',
selected: boolean},
{name: 'supper',
selected: boolean}
]
selectedDay: string;
}
可能我遗漏了什么,但我无法自己解决 - 我是 Angular 的新手。我将不胜感激!
所以制作后my own version of this。有几件事要讨论。首先是您在以下代码中使用 formControlName
<div class="col-md-3" formArrayName="meals">
<div><mat-checkbox formControlName="breakfast"> breakfast </mat-checkbox> </div>
<div><mat-checkbox formControlName="dinner"> dinner </mat-checkbox> </div>
<div><mat-checkbox formControlName="supper"> supper </mat-checkbox> </div>
</div>
问题是您的控件没有名称。如果您在控制台中拉出表单,您会注意到它变为 FormGroup -> Controls -> Meals -> Controls -> 0-3
。您必须再次遍历它们并尝试从对象本身中提取名称。 事实证明这真的很难,至少对我自己来说是这样。相反,您可能想像为 selectedDays
所做的那样将变量分配给数组的索引,然后 使用迭代器 访问 meals
属性 order.selectedDays[i]
.
如果你这样做,你最终会从硬编码各种复选框切换到选择一个 *ngFor
来自动提取信息并附加 selected
属性 in order.selectedDays[i].meals[m]
通过 [(ngModel)]
.
查看我链接到的 StackBlitz 示例,我知道它在设计方面看起来完全不同,但正在使用我提到的方法。您有兴趣查看提到的迭代方法的控件是 order-form
控件,请注意,在该控件中我使用 get meals(): FormArray { return this.form.get('meals') as FormArray; }
这允许我使用 [formControlName] = "i"
.