我有一个formArray,它由多个表单组组成。我需要根据数组中每个表单组中存在的布尔字段动态地对数组进行排序。
布尔字段是一个复选框,在任何给定的时间点只能检查一个复选框(模仿单选按钮)。因此,当单击一个复选框时,我需要根据所选的一个对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);
如果这不是正确的方法,那么解决这种情况的最佳方法是什么?
答案 0 :(得分:2)
我认为这不是最好的方法,但是从formarray中获取值,随心所欲地做任何事情并修补它们。
var myArray = this.formArray.value;
//do sorting here with myArray.sort
this.formArray.patchValue(myArray)
不要更改this.formArray的长度和架构。如果Patchvalue具有相同的结构,则它只能修补值。
答案 1 :(得分:1)
排序和过滤
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'));
答案 2 :(得分:0)
我已经有一个排序值数组,并使用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;
}
}
答案 3 :(得分:0)
它对我有用。我用单线做了这样的事情
this.names.patchValue(this.names.value.sort((a, b) => a.name.localeCompare(b.name)));
答案 4 :(得分:0)
sortFormArray() {
let sortArray = this.formArray.value;
sortArray.sort((a, b) => {
const A = a.primaryIndicator.toUpperCase();
const B = b.primaryIndicator.toUpperCase();
let comparison = 0;
if (A > B) {
comparison = 1;
} else if (A < B) {
comparison = -1;
}
return comparison;
});
this.appFormArrayData.setValue(sortArray);
}