Угловая вложенная форма Array - PullRequest
0 голосов
/ 07 октября 2019

Потратил почти день и узнал много нового о формах Angular Reactive, но мой вопрос остался без ответа. Я просто строю список элементов с кнопкой редактирования на каждом элементе. После того, как кнопка редактирования нажата, имя и описание элемента будут доступны для редактирования и отправки. Просто и отлично работает. Теперь я хочу добавить подпункт к этому элементу, поэтому у меня есть кнопка добавления, которая добавит массив форм в эту группу форм элементов и добавит подпункт. Это работает, но проблема в том, что когда я нажимаю на другой элемент, туда же добавляется тот же подэлемент. Похоже, я не специально добавляю подпункт к элементу, на котором нажимаю кнопку редактирования. Вот как я добавляю подпункт

buildItemsForm() {
 this.itemForm = this.fb.group({
  Description: [''],
  ItemCode: ['']
  Variations: this.fb.array([])
 });
}

addVariationToItem() {
  const variationsControl = this.itemForm.get('Variations') as FormArray; // here i need to specify the specific item
  variationsControl.push(this.itemVariation());
}

itemVariation() {
 return this.fb.group({
   color: ['']
})}

Это результат

 {
 Description: 'this is description'
 ItemCode: '123'
 Variations:[
  color:'red' ] // Added Here
 }
{
 Description: 'this is description2'
 ItemCode: '789'
 Variations:[
  color:'red' ] // But Adding it here too
 }

Обновление: вот HTML. Я получаю элементы из ответа бэкэнда, который зацикливается для отображения списка элементов, а затем внутри элементов отображается каждая форма, поэтому я не думаю, что мне нужно менять верхнюю форму на FromArray, если я не создал неправильный код.

<div *ngFor="let item of items; let i = index" class="card">
 <div class="item-info" *ngIf="!closeInEditItem(item)">
  <div>Description : {{item.Description}}</div>
  <div>Item Code : {{item.ItemCode}}</div>
  <div>Variation:</div>
  <button (click)="editItem(item)">Edit</button></div>
  <div class="form-group" *ngIf="editSate && itemToEdit.Id == item.Id">

  <form (ngSubmit)="updateItem(item)" [formGroup]="itemForm">
  <textarea matInput type="text" class="form-control" placeholder="Edit Description"
    formControlName="Description"></textarea>
  <input matInput type="text" class="form-control" placeholder="Edit Item Code" formControlName="ItemCode">
  <div formArrayName="Variations">
    <div *ngFor="let variationItem of itemForm.controls['Variations'].controls; let i=index">
      <input type="text" placeholder="Add Color Variation" formControlName="color">
    </div>
  </div>
 </form>

 </div>
</div>

Ответы [ 3 ]

1 голос
/ 07 октября 2019

В вашем случае должен быть другой formArray сверху, и внутри, чтобы вы могли иметь свою formGroup, поэтому код должен быть таким: -

  buildItemsFormGroup() {
    this.itemForm = this.fb.group({ itemArray: this.fb.array([]) });
    this.buildItemFormArray();
  }

  buildItemFormArray() {  // this method needs to be called for total number of items
    const itemArray = this.itemForm.get('itemArray') as FormArray;
    itemArray.push(this.fb.group({
      Description: [''],
      ItemCode: [''],
      Variations: this.fb.array([])
    }))
  }

  addVariationToItem(index: number) { // item index needs to be passed in which subitem has to be added.
    const itemArray = this.itemForm.get('itemArray') as FormArray;
    const variationsControl = itemArray.get(String(index)).get('Variations') as FormArray;
    variationsControl.push(this.itemVariation()); // other controls can be pushed here.
  }

  itemVariation() {
    return this.fb.group({
      color: ['']
    });
  }




 <form [formGroup]="itemForm">
        <div *ngFor="let itemDetail of itemForm.get('itemArray')['controls']; let i=index" formArrayName="itemArray">
            <div [formGroupName]="i">
                <div class="item-info">
                    <input type= "text"  formControlName="Description"> <br>
                    <input type="text" formControlName="ItemCode">
                    <div *ngFor="let variation of itemDetail.get('Variations')['controls']; let inIndex=index"
                        formArrayName="Variations">
                        <div [formGroupName]="inIndex">
                            <input type="text" formControlName = "color"> <!--All other controls to be added here-->
                </div>
                        </div>

                    </div>
                </div>
                <button (click)="addVariationToItem(i)">Add Color Variation</button>
            </div>
    </form>
1 голос
/ 07 октября 2019

Вы используете одну группу форм и ссылаетесь на нее в нескольких местах. Вам понадобится другой массив форм на верхнем уровне. Это выглядело бы как «описания», который представляет собой FromArray, содержащий группы форм описания. И вы можете найти их на основе идентификатора, чтобы добавить для каждого вложенного массива. Эта статья может помочь: https://alligator.io/angular/reactive-forms-formarray-dynamic-fields/

0 голосов
/ 07 октября 2019

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

**NOT work**
model=this.fb.group({
   color: ['']
}
addVariationToItem() {
  const variationsControl = this.itemForm.get('Variations') as FormArray; 
  //we are adding the same object
  variationsControl.push(this.model);
}

Но, повторяю, ваш код должен работать, потому что вы используете функцию, которая возвращает FormGroup, смотрите ваш код в stackblitz , проверьте .html

...