web-dev-qa-db-ja.com

Angular 4 FormArrayのインデックスに基づくpatchValue

ユーザーが空の作成されたコントロールに値を追加した後、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 } || {} });
}

これは、最初に作成され、すでに追加されているアイテムの更新に対して正常に機能します。問題は、空の値で追加される新しいアイテムにあります。新しいアイテムを追加するとき、properties.keyにfirebaseからのリターンキーを追加する必要があります

その新しいアイテムを保存するメソッドにpatchValueを追加しました

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

ただし、patchValueはまったく機能しません。新しい値を更新しようとすると、値がfirebaseに保存されていますが、空の値または初期値BuildItem()に設定された保存値が返されますが、patchValue

angular FormArray Documentation

コントロールの構造に一致する配列を受け入れ、はグループ内の正しいコントロールに値を一致させるために最善を尽くします[〜#〜] 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); 

空のbuildの初期コントロールを削除するために、これはどのような種類の良いコードでもないようです。

20
user1752532

FormArray#at + AbstractControl#patchValue

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

穴配列構造を更新する場合は、新しい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);
4
abahet