What is the ideal way to sort a FormArray object in Angular 2+?

点点圈 提交于 2021-02-18 21:00:47

问题


I have a formArray which consist of multiple form groups. I need to sort the array dynamically based on a boolean field present in each of the form group in the array.

The boolean field is a checkbox and at any given point of time only one checkbox can be checked (mimics radio button). So when a checkbox is clicked I need to sort the formArray based on the one that is selected.

I know the documentation suggests not to mess with the AbstractControls[] present in the formArray, so what would be the ideal way to dynamically sort the array ?

I have tried to slice the array and set the controls back into the formArray but I keep getting an error "Must supply a value for form control with name: '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);

If this is not the right way, what would be the best approach to solve such a scenario ?


回答1:


I do not think it would be the best way, but get the values from formarray, do whatever you want with it and patch them back.

var myArray = this.formArray.value;
//do sorting here with myArray.sort 
this.formArray.patchValue(myArray)

Do not change the length and schema of this.formArray. Patchvalue can only patch values, if they have same structure.




回答2:


Sorting and Filtering

  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);
    });
  }

then the call

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'));



回答3:


I already had an array of sorted values and use lodash's _.sortBy method like this:

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'
});

The trouble I had with using @Lorfme's answer, was that I was extending the base Angular form controls and setting additional properties on my classes. Like this:

class MyNewFormArray extends FormArray {
  private additionalStuff;

  constructor(formArgs, additionalStuff) {
    super(formArgs);
    this.additional = additionalStuff;
  }

  someMethod() {
    return this.additionalStuff;
  }
}



回答4:


It worked for me. I did something like this with a one-liner

this.names.patchValue(this.names.value.sort((a, b) => a.name.localeCompare(b.name)));




回答5:


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);

}



来源:https://stackoverflow.com/questions/49164800/what-is-the-ideal-way-to-sort-a-formarray-object-in-angular-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!