複数のフォームグループで構成されるformArrayがあります。配列内の各フォームグループに存在するブールフィールドに基づいて、配列を動的に並べ替える必要があります。
ブールフィールドはチェックボックスであり、任意の時点で1つのチェックボックスのみをチェックできます(ラジオボタンを模倣)。したがって、チェックボックスがクリックされたとき、選択されたものに基づいてformArrayをソートする必要があります。
ドキュメントがformArrayに存在するAbstractControls []を台無しにしないことを提案していることを知っています。それで、配列を動的にソートする理想的な方法は何でしょうか?
配列をスライスしてコントロールをformArrayに戻そうとしましたが、エラーが発生し続けます "フォームコントロールの値を 'primaryIndicator'という名前で指定する必要があります。"
const abstractControls = this.formArray.controls
.slice()
.sort((a, b) => {
return (a as FormGroup).get('primaryIndicator').value ? -1 : (b as FormGroup).get('primaryIndicator').value ? 1 : 0;
});
this.formArray.setValue(abstractControls);
これが正しい方法ではない場合、そのようなシナリオを解決するための最良のアプローチは何でしょうか?
私はそれが最善の方法だとは思いませんが、formarrayから値を取得し、それを使ってやりたいことを何でもして、パッチを当て直します。
var myArray = this.formArray.value;
//do sorting here with myArray.sort
this.formArray.patchValue(myArray)
This.formArrayの長さとスキーマは変更しないでください。 Patchvalueは、同じ構造の場合にのみ値にパッチを適用できます。
並べ替えとフィルタリング
sortArray(array: Array<any>, prop: string): Array<any> {
return array.sort((a, b) => {
prop.split('.').forEach(p => {
a = a[p];
b = b[p];
});
return (a > b) ? 1 : ((b > a) ? -1 : 0);
});
}
その後、呼び出し
const cartItemsFormArr = this.cartForm.get('cartItemsCtrls') as FormArray;
this.cartForm.controls['cartItemsCtrls'] = this._fb.array(
this.sortArray(cartItemsFormArr.controls.filter(ctrl => !ctrl.value['isChecked']), 'value.idShoppingCartDetail'));
私はすでにソートされた値の配列を持っていて、lodashの _.sortBy
このような方法:
const orderedTitles: Array<string> = ['title1', 'title2', 'title3'];
const pagesFormArray: FormArray = (this.form.get('pages') as FormArray);
pagesFormArray.controls = _.sortBy(pagesFormArray.controls, (control) => {
return _.indexOf(orderedTitles, control.value.title'
});
@Lorfmeの回答を使用する際の問題は、ベースAngularフォームコントロールを拡張し、クラスに追加のプロパティを設定することでした。次のようになります。
class MyNewFormArray extends FormArray {
private additionalStuff;
constructor(formArgs, additionalStuff) {
super(formArgs);
this.additional = additionalStuff;
}
someMethod() {
return this.additionalStuff;
}
}