排序 Angular 反应式数组真的需要排序控件和值吗?

Does sorting Angular reactive form array really requires sorting both controls and value?

我在我的 angular 应用程序中实现了 formArray sortBy 函数,方法是对 formArray 值进行排序并在排序后对其进行修补。

sortBy(FieldName: string) {
  let array = this.myItems.value;
  array.value.sort((a, b) => a[FieldName] - b[FieldName]);
  array.controls.sort((a, b) => a.value[FieldName] - b.value[FieldName]);
  this.myForm.controls.myItems.patchValue(array);
}

Working Stackblitz example

如您所见,我必须对 formArray 控件及其值进行排序。

我的问题是,我真的应该对两者都进行排序,还是有更好的做法或构建方法。看起来控件和值应该以某种方式绑定。

只需按 control 排序即可。

首先,将 myItem 设置为 this.form 不带括号。

this.myForm = this.formBuilder.group({
  header: ['hello form'],
  myItems: myFormArray,
});

然后将 FormArraycontrols 排序。

sortBy(FieldName: string) {
  this.myItems.controls.sort((a, b) => a.value[FieldName] - b.value[FieldName]);
}

如果需要排序myArray,可以通过this.myForm.getRawValue().myItems获取。

是的,您需要按两者“有点”排序,尽管您可以将其列为一行。我们需要记住,当你调用 myItems.value 时,这只是一个普通的 JS 对象,formarray 不再与此绑定,也就是说如果你之后修改 myItems.value,它不会反映在 formarray 中,因为 formarray 是 formcontrols/formgroups 的数组,而不是常规的 JS 数组。 myItems.value 也将仅反映 formarray 值的当前状态,因此如果将其分配给变量然后更改 formarray 的值,则分配的变量将具有原始值。

所以oneliner...你可以做

this.myItems.setValue(this.myItems.value.sort((a, b) => a[FieldName] - b[FieldName]));

并且如其他答案中所述,在构建表单时删除括号:

myItems: myFormArray

你修改后的 STACKBLITZ