gpt4 book ai didi

arrays - 带有 *ngFor 的 Angular2 奇怪的形式行为

转载 作者:太空狗 更新时间:2023-10-29 18:25:53 25 4
gpt4 key购买 nike

再次向那些看过我关于这个表格和瓶子的帖子的人问好......它又回来了。

在我开始解释之前,这里有一个working plunkr 显示了这个问题:

Working Plunkr

注意:我在第二个数组中显示 Bottle typeId,它清楚地显示了问题。


问题:

我正在检查绑定(bind)以确保正确传递了我选择的值,这时我遇到了以下情况的问题:

  • 1 : 添加一些 OrderReturn order 以便您有多个输入。
  • 2 : 选择一些类型并在这些输入中设置一些值。
  • 3 :如果您删除任何不是数组最后一个的输入,然后重新添加一个输入,即使绑定(bind)到 ngModel 仍然正确,值也会被弄乱。

有没有办法使用标准的 Template Driven Forms 来避免这种奇怪的行为?或者我必须通过 ReactiveForms 吗?


我将在这里解释我的大部分代码:

我将包含它们的名称typeId 的气瓶数组 (bottleArray) 作为 @Input 发送到我的表单()

我将这个数组及其对象深度克隆到两个单独的数组中:orderedClonedArrayBottlesreturnedClonedArrayBottles

然后我将值添加到我相应的显示数组:orderedBottlesreturnedBottles 现在有一个 count 值。

...
@Input() private bottleArray: Bottle[];

private orderedClonedArrayBottles: Bottle[] = [];
private returnedClonedArrayBottles: Bottle[] = [];
private orderedBottles: BottleCommand[] = [];
private returnedBottles: BottleCommand[] = [];

ngOnChanges(changes) {
// Get @Input data when it's ready
if (changes.bottleArray) {
// Cloning the Array AND the Bottles
this.orderedClonedArrayBottles = this.deepClone(changes.bottleArray.currentValue);
this.returnedClonedArrayBottles = this.deepClone(changes.bottleArray.currentValue);

// 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]);
}
}
}

我可以使用以下方法删除任何数组的任何索引:

removeRow(index: number, type: string, event: Event): void {
event.stopPropagation();
if (type == 'order') {
// Cleans the reference 'count' value.
this.orderedBottles[index].count = null;
this.orderedBottles.splice(index, 1);
} else {
this.returnedBottles[index].count = null;
this.returnedBottles.splice(index, 1);
}
}

我可以使用 2 个单独的按钮将项目推送到这 2 个数组中的任何一个:AddOrder()AddReturnOrder()(相同的代码):

addOrder(event: Event): void {
event.stopPropagation();
// Limits to the number of types
if (this.orderedBottles.length < this.orderedClonedArrayBottles.length) {
let index = this.getAvailableIndex(this.orderedBottles, this.orderedClonedArrayBottles);
this.orderedBottles.push(this.orderedClonedArrayBottles[index]);
}
}

为了避免在我的数组中推送现有引用,我使用以下方法获取第一个尚未显示的可用索引:

/**
* Gets the first available index from 2 arrays containing the same references.
*
* @param {Object[]} displayedArray Array containing the occupied indexes
* @param {Object[]} referenceArray Array containing all the indexes
* @return {number} Index of the first available position
*/
getAvailableIndex(displayedArray: Object[], referenceArray: Object[]): number {
let index: number = null;
// Gets the available indexes of Bottles by filtering the referenceArray with the displayedArray
let availablePositions: Object[] = referenceArray.filter(element => displayedArray.indexOf(element) < 0);
// Return the first position available
return index = referenceArray.indexOf(availablePositions[0]);
}

这是相应的 HTML :(在 Plunkr 中更清晰)

  <div fxLayout="row" style="max-width: 80%">
<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 bottleArray" [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', $event)">-</button>

{{orderedBottles[i].typeId}} -
{{orderedBottles[i].count}}
</div>

</div>


<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 type of bottleArray; let z = index" [value]="bottleArray[z].typeId">
{{ bottleArray[z].typeId }}
</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 style="margin-top: -20px;" class="button-row" type="button" (click)="removeRow(j, 'return', $event)">-</button>

{{returnedBottles[j].typeId}} -
{{returnedBottles[j].count}}
</div>

</div>
</div>

<div class="margin">
<button md-raised-button type="button" class="submit-button" (click)="addOrder($event)">Add Order</button>
<button md-raised-button type="button" class="submit-button" (click)="addReturnOrder($event)">Add Return Order</button>
</div>

最佳答案

使用 trackBy 避免困惑:

*ngFor="let bottle of orderedBottles; let i = index; trackBy: trackByFn"

trackByFn(index) {
return index;
}

它还能提高你的表现

Modified Plunker

另见

关于arrays - 带有 *ngFor 的 Angular2 奇怪的形式行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41738254/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com