Вложенные реактивные формы в Angular - PullRequest
0 голосов
/ 13 января 2020

Я пытаюсь динамически создать вложенный FormArray в моем приложении Angular 6.

У меня есть цитата, в которой есть коллекция элементов цитаты

export class Quote {
    quoteId: number;
    quoteItems: QuoteItem[]
    status: string;
}

export class QuoteItem {

    quoteItemId: number;
    description: string;
    quoteItemDetails: QuoteItemDetail[]
}

export class QuoteItemDetail {        
    quoteItemDetailId: number;
    rate: number;
    quantity: number;
    total: number;
}

У меня есть форма с объектом Quote, где пользователь может нажать на кнопку, чтобы добавить и удалить один или несколько QuoteItems.

Это мой код, где я инициализирую свою форму:

ngOnInit() {
    this.quoteForm = this.fb.group({
        status: [''],
        quoteItems: this.fb.array([])
    });
    this.addQuoteItem();
}

И вот как я получаю динамическое c добавление и удаление рабочих:

get quoteItems() {
    return this.quoteForm.get('quoteItems') as FormArray;
}  

addQuoteItem() {
    this.quoteItems.push(this.fb.group({
        description: '',
        quoteItemDetails: this.fb.array([])
    }));
}


removeQuoteV2Item(index) {
  this.quoteV2Items.removeAt(index);
}

И мой html:

<div formArrayName="quoteItems">

    <div @items *ngFor="let item of quoteItems.controls; let contentIndex=index" [formGroupName]="contentIndex">
        <input type="text" formControlName="description">
    </div>
</div>

<p>
  <a (click)="addQuoteItem()">Add Quote Item</a>
</p>

То, что я пытаюсь сделать, это иметь та же функциональность, но для моего массива QuoteItemDetail. Таким образом, пользователь может добавить один или несколько quoteItems, и в них добавить один или несколько QuoteItemDetails.

Я действительно застрял в первом пункте, я не могу понять, как получить оценщик массива формы, это не работает в качестве примера, так как я не уверен, как передать индекс:

get quoteItemDetails() {
  return this.quoteItems.get('quoteItemDetails') as FormArray;
}

1 Ответ

1 голос
/ 13 января 2020

Вы не сможете сделать это с помощью аксессора. Аксессор собирается дать вам ссылку на один атрибут. Но, как вы сказали, в этом случае вам нужен индекс, чтобы указать, какая ссылка FormIray для quoteItemDetails вам нужна (поскольку, насколько я понимаю, вы хотите создать FormArray в каждом quoteItem, поэтому каждый quoteItem может иметь несколько quoteItemDetails, верно?).

Хотя я не вижу проблем с этим. Вместо того, чтобы делать это с аксессором, как вы сделали с quoteItems, вам придется делать это с методом, принимающим один нужный вам параметр - индекс. Примерно так:

quoteItemDetails(quoteItemIndex: number): FormArray {
  return this.quoteItems.at(quoteItemIndex).get('quoteItemDetails') as FormArray;
}

И тогда вы представляете это в шаблоне:

<div formArrayName="quoteItems">

  <div @items *ngFor="let item of quoteItems.controls; let contentIndex=index" [formGroupName]="contentIndex">
    <input type="text" formControlName="description">
    <div *ngFor="let quoteItemDetail of quoteItemDetails(contentIndex).controls; let detailIndex=index" [formArrayName]="detailIndex">
      <input type="number" formControlName="description" />
    </div>
  </div>
</div>

Надеюсь, это вам поможет. Я не тестировал код, но решение должно быть где-то там.

...