【问题标题】:Collation for MatSort with languages where alphabetical order is different from Unicode order?MatSort 的排序规则与字母顺序与 Unicode 顺序不同的语言?
【发布时间】:2019-09-04 13:58:08
【问题描述】:

在挪威和丹麦字母中,挪威/丹麦字符的正确顺序是:

  1. Æ
  2. Ø

但是,MatSort 对这些字符使用 Unicode 顺序:

  1. 埃 (197)
  2. Æ (198)
  3. Ø (216)

能否以某种方式实施排序规则来解决这个问题?

这是一个堆栈闪电战,其中包含一个可以按“No”排序的表格。和“名称”:

https://stackblitz.com/edit/angular-an1uqc-8mdqns

这是表格中的数据:

 {position: 1, name: 'Alpha', description: 'Test123'},
  {position: 2, name: 'Bravo',  description: '0'},
  {position: 3, name: 'Charlie', description: 'aaa'},
  {position: 4, name: 'Delta',  description: ''},
  {position: 5, name: 'Echo',  description: '1'},
  {position: 6, name: 'Foxtrot',  description: '2'},
  {position: 7, name: 'ÆGamma',  description: ''},
  {position: 8, name: 'ØHotel',  description: '3'},
  {position: 9, name: 'ÅIndigo',  description: '1000'},

];

根据挪威/丹麦字母表对最后三个项目(ÆGamma、ØHotel 和 ÅIndigo)进行排序的正确方法是:

  1. Æ伽玛
  2. Ø酒店
  3. Å靛蓝

但 MatSort 对这些字符使用 Unicode 数字并改为这样排序:

  1. Å靛蓝 (197)
  2. Æ伽玛 (198)
  3. Ø酒店 (216)

感谢阅读! :]

【问题讨论】:

  • 您将需要利用 matSortChange 事件来实现自定义排序算法。官方文档示例展示了如何使用 matSortChange beta-angular-material-io.firebaseapp.com/components/sort/…
  • 我刚刚检查了 JavaScript 对这些语言的本地化排序的支持,语言代码 'da' 为您提供了您想要的排序,但 'no' 没有 - 使用 'no',排序是["ÆGamma", "ÅIndigo", "ØHotel"].
  • @kshetline 是否可以通过 MatSort 使用本地化排序?
  • 据我所知,只有@Alexander Staroselsky 的建议可以帮助您做到这一点。

标签: angular typescript sorting angular-material collation


【解决方案1】:

您需要使用matSortChange 来实现自定义排序,在本例中为本地化排序。这可以使用String.prototype.localCompare 和语言标识符da-DK 来完成:

模板:

<table
  mat-table [dataSource]="sortedData"
  matSort (matSortChange)="sortData($event)"
  class="mat-elevation-z8">

组件:

sortData(sort: Sort) {
  const data = ELEMENT_DATA.slice();
  if (!sort.active || sort.direction === '') {
    this.sortedData = data;
    return;
  }

  this.sortedData = data.sort((a, b) => {
    const isAsc = sort.direction === 'asc';
    switch (sort.active) {
      case 'position': return compareNumber(a.position, b.position, isAsc);
      case 'name': return compareString(a.name, b.name, isAsc);
      case 'description': return compareString(a.description, b.description, isAsc);
      default: return 0;
    }
  });
}

// ...

function compareNumber(a: number, b: number, isAsc: boolean) {
  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}

function compareString(a: string, b: string, isAsc: boolean) {
  return a.localeCompare(b, 'da-DK') * (isAsc ? 1 : -1);
}

这里有一个example 在行动。

排序结果如下:

1 Alpha
// ...
6 Foxtrot
7 ÆGamma
8 ØHotel
9 ÅIndigo

然后反过来:

9 ÅIndigo
8 ØHotel
7 ÆGamma
6 Foxtrot
// ...
1 Alpha

希望对您有所帮助!

【讨论】:

  • 太棒了!我也在 Angular GitHub 上问过这个问题,他们不知道,所以我会在这里重新发布您的示例,以便更多人可以看到这个! ;) github.com/angular/components/issues/16923
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-19
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多