Arhn - архитектура программирования

Проблемы с привязками моделей в формах с несколькими *ngFor

Я использую форму, в которой несколько раз повторяется следующая модель:

  • У меня есть выбор, где я могу выбрать любой тип 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, но понятия не имею, поможет это или нет.


Ответы:


1

Вы клонируете файл bottleArray. Но в вашем случае объекты бутылки не клонируются. Одни и те же ссылки помещаются в два массива.

Проверьте этот ответ.

Возможно, вам придется использовать Object.assign для каждого объекта бутылки. Если у вас есть вложенные объекты, вам придется пройти по свойствам и скопировать.

13.01.2017
  • Безупречная работа. Большое спасибо ! 13.01.2017
  • Для тех, кто в этом нуждается: я разместил свой собственный метод deepClone() по ссылке в ответе. 13.01.2017
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..