【问题标题】:Custom sorting mat-table when each row is represented by FormGroup当每行由 FormGroup 表示时自定义排序 mat-table
【发布时间】:2021-05-11 01:19:04
【问题描述】:

我有一个mat-table,其中datasource 是MatTableDataSource<FormGroup>。代表每一行的FormGroup 显然是另一个FormGroup 的FormArray 属性。所以,表单的架构大致是这样的:

FormGroup(persons: FormArray(FormGroup[firstName, lastName]))

我能够通过以下方式覆盖过滤功能:

this.dataSource.filterPredicate = someCustomFilterFunction

但是,如果我尝试使用以下命令覆盖排序: this.dataSource.data.sort((a: FromGroup, b: FormGroup): number...)

我的表格很混乱。事实上,看起来其中一个表单控件认为它是另一行中的另一个表单控件。

如果我不必在已经排序的状态下重新创建整个排序,就没有办法对其进行排序吗?

【问题讨论】:

  • 请分享您的代码,然后才能回答您的问题
  • 看起来没有对 FormArray 中的项目进行排序的好方法:stackoverflow.com/questions/49164800/…
  • 刚刚找到我的答案...不可能像常规数组一样对其进行排序(FormArray api doc 中的最后一段):“从表单数组中添加或删除控件要更改数组中的控件, 使用 FormArray 本身中的 push, insert, removeAt 或 clear 方法。这些方法确保控件在表单的层次结构中正确跟踪。不要修改用于直接实例化 FormArray 的 AbstractControls 数组,因为这会导致奇怪和意外的行为例如损坏的变更检测。”

标签: angular angular-material angular-reactive-forms


【解决方案1】:

当你说“代表每一行的 FormGroup 显然是另一个 FormGroup 的 FormArray 属性”时,我真的不太确定。如果你有一个 MatDataSource,你有 NOT 一个 FormGroup 的 FormArray,只是一个 FormGroups 的数组

在这种情况下,您唯一需要的是提供自定义排序功能。请记住,您是在比较 FormGroups:

  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
    this.dataSource.sortData = (data: FormGroup[], sort: MatSort) => {
      //in "data" you has the array of FormGroup
      //in sort.direction you has "asc,"desc" or ""
      //in sort.active you has the column you clicked
      const factor =
        sort.direction == "asc" ? 1 : sort.direction == "desc" ? -1 : 0;
      if (factor) {
        data = data.sort((a: FormGroup, b: FormGroup) => {
          const aValue = a.get(sort.active) ? a.get(sort.active).value : null;
          const bValue = a.get(sort.active) ? b.get(sort.active).value : null;
          return aValue > bValue ? factor : aValue < bValue ? -factor : 0;
        });
      }
      return data;
    };
  }

注意:我假设一个 dataSource 一个 FormGroup 的数组创建为

dataSource = new MatTableDataSource<any>(
    ELEMENT_DATA.map(
      x =>
        new FormGroup({
          position: new FormControl(x.position),
          name: new FormControl(x.name),
          weight: new FormControl(x.weight),
          symbol: new FormControl(x.symbol)
        })
    )
  );

见stackblitz

更新如果你想要一个formArray,请记住dataSource是关于yourFormArray.controls的,有些像

  myArray=new FormArray(...)
  //see that dataSource is MatDataSource(this.myArray.controls)
  dataSource = new MatTableDataSource<any>(this.myArray.controls);

【讨论】:

  • 刚刚找到我的答案...不可能像常规数组一样对其进行排序(FormArray api doc 中的最后一段):“从表单数组中添加或删除控件要更改数组中的控件, 使用 FormArray 本身中的 push, insert, removeAt 或 clear 方法。这些方法确保控件在表单的层次结构中正确跟踪。不要修改用于直接实例化 FormArray 的 AbstractControls 数组,因为这会导致奇怪和意外的行为例如损坏的变更检测。”
  • 谢谢,这对于在不了解 MatSort 的情况下实现不区分大小写的排序非常有帮助。我刚刚在 aValue/bValue 上添加了 .toLowerCase()
猜你喜欢
  • 2019-10-27
  • 1970-01-01
  • 2021-04-04
  • 2019-08-15
  • 2021-05-20
  • 2019-08-08
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
相关资源
最近更新 更多