Я использую форму, в которой несколько раз повторяется следующая модель:
- У меня есть выбор, где я могу выбрать любой тип
Bottle
, который у меня есть. - Вход, где я могу выбрать количество бутылок для выбранного типа.
Этот шаблон повторяется для двух массивов Bottle (тип Bottle
состоит из Id
и Name
) следующим образом:
- Массив из
orderedBottles
, где пользователь может заказать несколько бутылок. - Массив из
returnedBottles
, где пользователь может вернуть несколько бутылок.
Я хочу иметь возможность выбрать любой тип бутылки и соответствующий счет при отправке, но я считаю, что что-то упускаю, потому что поведение все испорчено:
- Входы 2-х массивов связаны друг с другом,
- Когда я меняю некоторые параметры в выборе, иногда обновляются другие варианты выбора, а это не то, что я хочу (очевидно)...
Вот рабочий пример в 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
, которые получают свои значения из двух клонированных заранее.
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
, но понятия не имею, поможет это или нет.