Angular FormArray или FormGroup - с дополнительными данными - PullRequest
0 голосов
/ 02 марта 2019

У меня есть таблица, которая динамически создается, и она отображает данные следующим образом:

<table>
  <tr *ngFor="let product of products">
    <td>{{product.name}}</td>
    <td>{{product.description}}</td>
    <td>{{product.value}}</td>
    <!-- BELOW IS WHERE A NEW VALUE WILL BE ENTERED -->
    <td><input type="text" value=""></td>
  </tr>
</table>

Я прочитал, что соответствующий способ обработки этого - это FormsArray.Но я также читал, что подходящий способ использования FormsArray - получить его массив элементов управления:

<table>
  <tr *ngFor="let product of this.form.get('productCollection').controls; let i = index;"
     [formGroupName]="i">
    <td>{{product.name}}</td>
    <td>{{product.description}}</td>
    <td>{{product.value}}</td>
    <!-- BELOW IS WHERE A NEW VALUE WILL BE ENTERED -->
    <td><input type="text" formControlName="name"></td>
  </tr>
</table>

Проблема в том, что у меня нет доступа к значению описания здесь.И я не нашел способа передать это как метаданные в элемент управления, чтобы я мог показать это.

Итак, вопрос для чего-то вроде этого, какой правильный подход?Это FormArray?Это массив FormControls в одной FormGroup?Или каждый контроль формы должен быть сам по себе?Я открыт для предложений о том, как сделать эту работу.

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

В этом случае я бы перебрал реальный массив продуктов, а не массив элементов управления, поскольку вам нужно больше информации из данных, чем из элемента управления.

Шаблон

<form [formGroup]="form">
  <table formArrayName="productRows">
    <tr *ngFor="let product of products; let i = index;" [formGroupName]="i">
      <td>{{product.name}}</td>
      <td>{{product.description}}</td>
      <td><input type="text" formControlName="value"></td>
    </tr>
  </table>
</form>

Компонент

buildForm() {
  this.form = this.fb.group({
    productRows: this.fb.array(this.initProductRows())
  });
  this.form.valueChanges.subscribe((change) => {
    this.products.forEach((product, index) => {
      product.value = change.productRows[index].value;
    })
  });
}

initProductRows() {
  return this.products.map(product => {
    return this.fb.group({
      value: product.value
    });
  });
}

Часть ключа здесь инициализирует ваш FormArray в начале при создании формы такой же длины (и имеют те же значения), что и данные продукта.

Кроме того, я не был уверен, пытаетесь ли вы сохранить новое значение обратно в исходные данные продукта, но если это так, тогда я добавил прослушиватель valueChanges, чтобы вы могли записать его обратно.Все это можно увидеть в Stackblitz ниже.

https://stackblitz.com/edit/angular-edawnf

0 голосов
/ 02 марта 2019

Я думаю, я мог бы найти ответ.Ключ может состоять в том, чтобы НЕ делать FormArray, а скорее массив FormControls в FormGroup.Таким образом, я могу продолжать использовать список со всеми имеющимися у него данными, а затем добавить поле на основе FormGroup.Таким образом, конечный результат будет:

<table>
  <tr *ngFor="let product of products">
    <td>{{product.name}}</td>
    <td>{{product.description}}</td>
    <td>{{product.value}}</td>
    <!-- BELOW IS WHERE A NEW VALUE WILL BE ENTERED -->
    <td>
      <div formGroupName="productCollection">
        <input type="text" formControlName="name">
      </div>
    </td>
  </tr>
</table>

Если я ошибаюсь или если у кого-то есть способ получше, непременно покажите это и дайте мне знать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...