具有多个 *ngFor 的表单上的模型绑定问题
Issues with model bindings on Forms with several *ngFor
我使用的表格重复了几次以下模型:
- 我有一个 select,我可以在其中选择任何类型的
Bottle
。
- 我可以select selected 类型的瓶子数量的输入。
对 2 个 Bottle 数组重复此模式(Bottle
类型由 Id
和 Name
组成)如下:
orderedBottles
的数组,用户可以在其中订购一些瓶子。
returnedBottles
的数组,用户可以在其中 return 一些瓶子。
我希望能够在提交时选择任何类型的瓶子和相应的数量,但我相信我遗漏了一些东西,因为行为全乱了:
- 两个数组的输入是相互关联的,
- 当我更改 select 中的某些选项时,有时其他 select 会更新,这不是我想要的(显然)...
这是一个 plunkr 中的工作示例:http://plnkr.co/edit/1z6dN6?p=preview
这是我的 html 文件(我使用的是 AngularMaterial 2):
<div fxLayout="row" style="max-width: 80%">
<!-- ORDERED BOTTLES -->
<div fxLayout="column" style="min-width: 50%">
<div fxLayout="row" style="max-width: 100%" *ngFor="let bottle of orderedBottles; let i = index">
<md-select class="select" placeholder="Select bottle type" name="orderedTypeSelect_{{i}}" [(ngModel)]="orderedBottles[i].typeId">
<md-option class="options" *ngFor="let type of orderedClonedArrayBottles" [value]="type.typeId">
{{ type.name }}
</md-option>
</md-select>
<md-input-container class="container">
<input md-input type="number" name="orderedBottleInput_{{i}}" autocomplete="off" [(ngModel)]="orderedBottles[i].count"
step="1" min="0" max="99">
</md-input-container>
<button class="button-row" type="button" (click)="removeRow(i, 'order')">-</button>
</div>
</div>
<!-- RETURNED BOTTLES -->
<div fxLayout="column" style="min-width: 50%">
<div fxLayout="row" style="max-width: 100%" *ngFor="let bottle of returnedBottles; let j = index">
<md-select class="select" placeholder="Select bottle type" name="returnedTypeSelect_{{j}}" [(ngModel)]="returnedBottles[j].typeId">
<md-option class="options" *ngFor="let typed of returnedClonedArrayBottles" [value]="typed.typeId">
{{ typed.name }}
</md-option>
</md-select>
<md-input-container class="container">
<input md-input type="number" name="returnedBottleInput_{{j}}" autocomplete="off" [(ngModel)]="returnedBottles[j].count"
step="1" min="0" max="99">
</md-input-container>
<button class="button-row" type="button" (click)="removeRow(j, 'return')">-</button>
</div>
</div>
</div>
添加一些解释,这是一个子组件,它有一个 Bottle
数组作为 @Input()
,我将其克隆到 2 个不同的数组(orderedClonedArrayBottles
和 returnedClonedArrayBottles
) 这样我的父数组就不会从子更新中更新。
然后我用 orderedBottles
数组和 returnedBottles
显示我的瓶子,它们从预先克隆的 2 个中获取它们的值。
ngOnChanges(changes) {
// Get @Input data when it's ready
if (changes.bottleArray) {
// Cloning
//this.orderedClonedArrayBottles = [...changes.bottleArray.currentValue];
//this.returnedClonedArrayBottles = [...changes.bottleArray.currentValue];
this.orderedClonedArrayBottles = Array.from(changes.bottleArray.currentValue as Bottle[]);
this.returnedClonedArrayBottles = Array.from(changes.bottleArray.currentValue as Bottle[]);
console.log(this.orderedClonedArrayBottles);
console.log(this.returnedClonedArrayBottles);
// Display first rows
if (this.orderedClonedArrayBottles.length > 0) {
this.orderedBottles.push(this.orderedClonedArrayBottles[0]);
}
if (this.returnedClonedArrayBottles.length > 0) {
this.returnedBottles.push(this.returnedClonedArrayBottles[0]);
}
}
}
我不知道为什么这不能正常工作,很可能是因为我没有按应有的方式管理 *ngFor
。我看过关于 trackBy
的关于 *ngFor
的帖子,但我不知道这是否有帮助。
您正在克隆 bottleArray
。但在你的情况下,瓶子对象没有被克隆。相同的引用被压入两个数组。
检查此 。
您可能必须对每个瓶子对象使用 Object.assign
。
如果您有嵌套对象,则必须遍历属性并复制。
我使用的表格重复了几次以下模型:
- 我有一个 select,我可以在其中选择任何类型的
Bottle
。 - 我可以select selected 类型的瓶子数量的输入。
对 2 个 Bottle 数组重复此模式(Bottle
类型由 Id
和 Name
组成)如下:
orderedBottles
的数组,用户可以在其中订购一些瓶子。returnedBottles
的数组,用户可以在其中 return 一些瓶子。
我希望能够在提交时选择任何类型的瓶子和相应的数量,但我相信我遗漏了一些东西,因为行为全乱了:
- 两个数组的输入是相互关联的,
- 当我更改 select 中的某些选项时,有时其他 select 会更新,这不是我想要的(显然)...
这是一个 plunkr 中的工作示例:http://plnkr.co/edit/1z6dN6?p=preview
这是我的 html 文件(我使用的是 AngularMaterial 2):
<div fxLayout="row" style="max-width: 80%">
<!-- ORDERED BOTTLES -->
<div fxLayout="column" style="min-width: 50%">
<div fxLayout="row" style="max-width: 100%" *ngFor="let bottle of orderedBottles; let i = index">
<md-select class="select" placeholder="Select bottle type" name="orderedTypeSelect_{{i}}" [(ngModel)]="orderedBottles[i].typeId">
<md-option class="options" *ngFor="let type of orderedClonedArrayBottles" [value]="type.typeId">
{{ type.name }}
</md-option>
</md-select>
<md-input-container class="container">
<input md-input type="number" name="orderedBottleInput_{{i}}" autocomplete="off" [(ngModel)]="orderedBottles[i].count"
step="1" min="0" max="99">
</md-input-container>
<button class="button-row" type="button" (click)="removeRow(i, 'order')">-</button>
</div>
</div>
<!-- RETURNED BOTTLES -->
<div fxLayout="column" style="min-width: 50%">
<div fxLayout="row" style="max-width: 100%" *ngFor="let bottle of returnedBottles; let j = index">
<md-select class="select" placeholder="Select bottle type" name="returnedTypeSelect_{{j}}" [(ngModel)]="returnedBottles[j].typeId">
<md-option class="options" *ngFor="let typed of returnedClonedArrayBottles" [value]="typed.typeId">
{{ typed.name }}
</md-option>
</md-select>
<md-input-container class="container">
<input md-input type="number" name="returnedBottleInput_{{j}}" autocomplete="off" [(ngModel)]="returnedBottles[j].count"
step="1" min="0" max="99">
</md-input-container>
<button class="button-row" type="button" (click)="removeRow(j, 'return')">-</button>
</div>
</div>
</div>
添加一些解释,这是一个子组件,它有一个 Bottle
数组作为 @Input()
,我将其克隆到 2 个不同的数组(orderedClonedArrayBottles
和 returnedClonedArrayBottles
) 这样我的父数组就不会从子更新中更新。
然后我用 orderedBottles
数组和 returnedBottles
显示我的瓶子,它们从预先克隆的 2 个中获取它们的值。
ngOnChanges(changes) {
// Get @Input data when it's ready
if (changes.bottleArray) {
// Cloning
//this.orderedClonedArrayBottles = [...changes.bottleArray.currentValue];
//this.returnedClonedArrayBottles = [...changes.bottleArray.currentValue];
this.orderedClonedArrayBottles = Array.from(changes.bottleArray.currentValue as Bottle[]);
this.returnedClonedArrayBottles = Array.from(changes.bottleArray.currentValue as Bottle[]);
console.log(this.orderedClonedArrayBottles);
console.log(this.returnedClonedArrayBottles);
// Display first rows
if (this.orderedClonedArrayBottles.length > 0) {
this.orderedBottles.push(this.orderedClonedArrayBottles[0]);
}
if (this.returnedClonedArrayBottles.length > 0) {
this.returnedBottles.push(this.returnedClonedArrayBottles[0]);
}
}
}
我不知道为什么这不能正常工作,很可能是因为我没有按应有的方式管理 *ngFor
。我看过关于 trackBy
的关于 *ngFor
的帖子,但我不知道这是否有帮助。
您正在克隆 bottleArray
。但在你的情况下,瓶子对象没有被克隆。相同的引用被压入两个数组。
检查此
您可能必须对每个瓶子对象使用 Object.assign
。
如果您有嵌套对象,则必须遍历属性并复制。