Angular 4 patchValue на основе индекса в FormArray

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

В настоящее время, когда пользователь выбирает добавить новый элемент, который я строю на formArray с пустыми значениями.

buildItem(item?: any, key?: any): FormGroup {
  // Item will pass undefined for initial buildItem in onLoad and new items
  let itemName: string;
  let keyValue: string;
  if (item === undefined) { 
     itemName = ''; key = '' }  
  else { 
     itemName = item.name; keyValue = key 
  };

  /**
   * Builds a single item for form group array in the collectionForm.
   */
   return this.formBuilder.group({ 
                item: [itemName || '', Validators.required], 
                properties: { item, key: key } || {} });
}

Это прекрасно работает для первоначального создания и обновления уже добавленных элементов. Проблема с новыми элементами, которые добавляются с пустыми значениями. Когда я добавляю новый элемент, мне нужно добавить ключ возврата из firebase в properties.key

В методе сохранения этого нового элемента я добавил patchValue

this.items.patchValue([{ 
         // item being returned from firebase promise
         item: item.name, 
         properties: { item: item.name, key: item.$key' } 
}]);

Тем не менее patchValue не работает вообще. Когда я пытаюсь обновить это новое значение, хотя значения были сохранены в базе данных, я все равно получаю возврат для значений как пустых или сохраненных значений, установленных на начальном BuildItem() а не обновленные значения в patchValue

Я вижу на угловой FormArray Документация, которая

Он принимает массив, который соответствует структуре элемента управления, и сделает все возможное, чтобы сопоставить значения с правильными элементами управления в группе. REF

Означает ли это, что он может обновлять это значение, а может и не обновлять его? Я полагаю, что если я могу добавить индекс для значения, которое я хочу исправить, то это не должно быть проблемой вообще. как с removeAt(idx)

Так что, если я могу написать что-то вроде

this.form.patchValue.atIndex(this.idx,[{ 
         item: item.name, 
         properties: { item: item.name, key: item.$key' } 
}];

Но не уверен, что смогу это сделать... ну, конечно, уверен, что в такой форме это невозможно. Есть ли способ специально нацелиться на предмет, который пропатчен в formArray или я, возможно, не правильно понимаю это.

Я могу сойти с рук, выдвинув новое значение на formArray

this.items.push(this.buildItem(...));

Однако тогда я должен добавить

this.items.removeAt(this.idx); 

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

5 ответов

Решение

Использование FormArray#at + AbstractControl#patchValue:

this.items.at(index).patchValue(...);

Вы можете сделать это, просто создав новый FormControl, если вы хотите обновить структуру массива отверстий:

this.form.setControl('items',  new FormControl(arrayItemsValue));

Или удалив все элементы перед их обновлением:

const items = (<FormArray>this.form.get('items'));
 for (let i = 0; i < items.length; i++) {
     items.removeAt(i);
 }
 this.form.get('items').setValue(arrayItemsValue);

Как сказал developer033:

Используйте FormArray#at + AbstractControl#patchValue

Но как? Вот пример:

В HTML:

<div formArrayName="alternateEmail" *ngFor="let control of alternateEmail.controls; index as i">
  <input type="text" placeholder="Type an alternative email" [formControlName]="i"><input>
</div>

В классе:

get alternateEmail(){  return this.registrationForm.get('alternateEmail') as FormArray }

И собственно метод патча:

patchDynamicFormBlockValue(){
  this.alternateEmail.at(<index>).patchValue('patchmail@gmail.com')
}

Вы также можете удалить as FormArray и бросайте, когда вам нужно:

(<FormArray>this.alternateEmail).at(<index>).patchValue('test@gmail.com')

      let rows = this.manageOrderForm.get('ordersForm') as FormArray;
    rows.controls[this.index].patchValue({totalAmount:totalPrice});
    this.index = this.index + 1;

formarray устанавливает значение по индексу

      ((this.form.get('controls') as FormArray).at(index) as FormGroup).get('description').patchValue(item.description);

В файле TS используйте ниже в качестве примера

пусть taskListArrays = this.projectParentForm.get('TaskList') как FormArray

taskListArrays.controls[rowindex].patchValue({"Электронная почта": " contacttotanuj@gmail.com"});

Другие вопросы по тегам