Angular Реактивная форма - Массив формы - Как мне установить FormArray с оператором распространения? - PullRequest
1 голос
/ 09 апреля 2020

У меня есть formarray. Если я инициализирую его с помощью formbuilder и пу sh на него, это, кажется, работает хорошо. Если я беру тот же массив, из которого отправляю элементы, и пытаюсь добавить все сразу с помощью оператора распространения, я получаю ошибку «Ошибка ОШИБКИ: не удается найти элемент управления с путем:« sizesArray -> 0 »»

Мой вопрос в соответствии с духом функционально-реактивного программирования ngrx / rsjx, как я могу сохранить Formarray «неизменным» и присвоить ему значение из FormGroup [], а не очищать, зацикливать и выдвигать?

Вот соответствующий код:

sizesArray: FormArray;
sizesArray2: FormArray;
sizes: Observable<SizeModel[]>;

constructor(
    private productStore: Store<productState.State>,
    private fb: FormBuilder
  ) {
    this.sizes = productStore.select(productState.selectSizes);
  }

ngOnInit() {


    this.sizesArray = this.fb.array([]);
    this.sizesArray2 = this.fb.array([]);

    this.sizes
      .pipe(
        skipWhile(sizes => !sizes),
        map(sizes => {
         return sizes.map(size => this.fb.group({size}));
        }
       )
      )
      .subscribe(
        sizes => {
          // this is the code I want to use.  that throws the error
          this.sizesArray = this.fb.array([...sizes]);

          // this code works, but I don't know how it's different than the code above
          this.sizesArray2.clear();
          sizes.forEach( size => {
            this.sizesArray2.push(size);
          });

        }
      );

    this.sizeForm = this.fb.group({
      sizesArray: this.sizesArray
    });

  }

и мой шаблон:

...
<form [formGroup]="sizeForm">
      <fieldset  id="size-container">
        <legend>Sizes</legend>
        <div formArrayName="sizesArray" >
            <div *ngFor="let size of sizesArray.controls; let i = index;" [formGroupName]="i">
            <app-size-form
              formControlName="size"
              (deleteClicked)="deleteSize(i);">
            </app-size-form>
          </div>
        </div>
      </fieldset>
      <button (click)="addSize()" id="size-button">Add Size</button>
      <button mat-button matStepperPrevious>Back</button>
      <button mat-button (click)="submit()">Save</button>
    </form>
...

Спасибо!

1 Ответ

1 голос
/ 09 апреля 2020

Я думаю, проблема в том, что вы меняете ссылки .

this.sizeForm = this.fb.group({
  sizesArray: this.sizesArray
});

На данный момент sizeArray указывает на значение, на которое ссылается this.sizesArray, что составляет this.fb.array([]). Затем при следующем обратном вызове вашего подписчика вы меняете ссылки. Это значение также «захватывается» formControlName='sizesArray', что означает, что

<div *ngFor="let size of sizesArray.controls; let i = index;" [formGroupName]="i">

создаст количество FormGroup экземпляров, которые являются дочерними элементами контейнера sizesArray, который пуст.

Теперь this.sizesArray (по которому вы перебираете шаблон) указывает на что-то еще, а именно: this.fb.array([...sizes]).

Итак, в основном происходит то, что sizesArray ( дочерний элемент sizeForm) указывает на пустое FormArray, а this.sizesArray указывает на непустое FormArray.

То, что вы могли бы сделать в этом случае, было бы следующим:

.subscribe(sizes => {
  this.sizeForm.setControl('sizeArray', this.fb.array(sizes))
})
...