Angular Material 中的默认排序 - 排序标题

Posted

技术标签:

【中文标题】Angular Material 中的默认排序 - 排序标题【英文标题】:Default sorting in Angular Material - Sort header 【发布时间】:2018-03-26 08:51:34 【问题描述】:

如何更改下面的 Angular Material 代码,以便数据表按“名称”列排序,默认为升序。必须显示箭头(指示当前排序方向)。

这就是我想要实现的目标:

原码:

<table matSort (matSortChange)="sortData($event)">
  <tr>
    <th mat-sort-header="name">Dessert (100g)</th>
    <th mat-sort-header="calories">Calories</th>
    <th mat-sort-header="fat">Fat (g)</th>
    <th mat-sort-header="carbs">Carbs (g)</th>
    <th mat-sort-header="protein">Protein (g)</th>
  </tr>

  <tr *ngFor="let dessert of sortedData">
    <td>dessert.name</td>
    <td>dessert.calories</td>
    <td>dessert.fat</td>
    <td>dessert.carbs</td>
    <td>dessert.protein</td>
  </tr>
</table>

我正在尝试这样的事情,但它不起作用(未显示箭头,未排序)

<table matSort (matSortChange)="sortData($event)" matSortActive="name" matSortStart="asc" matSortDisableClear>

这里是Plunker的链接

【问题讨论】:

可以在ngOnInit上调用this.sortData(active: "name", direction: "asc")检查plunker @PankajParkar 这不是正确的解决方案。表格已排序,但排序标题不知道它,并且箭头(指示当前排序方向)不显示。 【参考方案1】:

您将matSortStart 误认为matSortDirection

试试这个:

<table matSort (matSortChange)="sortData($event)" matSortActive="name" matSortDirection="asc" matSortDisableClear>

https://stackblitz.com/edit/angular-defaultsort?file=src/app/sort-overview-example.html

matSortStart 可用于反转排序时使用的循环(例如,当用户单击排序时,它从 desc 而不是 asc 开始)。

编辑:感谢 Ben 提供更新的示例

【讨论】:

此方法仅适用于第一次。更改表的数据源后,我尝试重新设置matSortActivematSortDirection,但未显示小箭头 样本好像不行了,我做了一个新的:stackblitz.com/edit/angular-defaultsort?file=src/app/… 您可以使用this solution 触发排序并修复隐藏箭头错误。我正在使用没有数据源的 mat-sort-header,这是唯一有效的修复方法。 @GilEpshtain 来解决这个问题,请在下面使用@Aman Madiiarbekov 的答案。 您好,如果我的表格实现了分页,如何保证activedirection的参数能延续到下一页?【参考方案2】:

您可以通过调用数据源的sort(Sortable) 方法以编程方式对表进行排序。假设您有一个 dataSource 数据源的组件属性:

// to put next to the class fields of the component
@ViewChild(MatSort) sort: MatSort

// to put where you want the sort to be programmatically triggered, for example inside ngOnInit
this.sort.sort(( id: 'name', start: 'asc') as MatSortable);
this.dataSource.sort = this.sort;

【讨论】:

这正是我正在寻找的,但唯一的问题是它触发了matSortChange 事件。有没有办法在不触发事件的情况下设置排序? 没有。这就是排序被调用的方式。为什么不希望触发 matSortChange 事件? 因为我已将其设置为使用列的asc/desc 更新cookie,并且如果每次加载页面时都调用它,那么每次都会不同 如果您使用 mat-sort-header 没有数据源,您可以使用此解决方案以编程方式触发排序:github.com/angular/components/issues/… 这仅对我第一次有效,在另一次初始化表后顺序错误。以下来自@Aman Madiiarbekov 的答案为我完成了这项工作。【参考方案3】:
@ViewChild(MatSort) sort: MatSort;

this.dataSource.sort = this.sort;

const sortState: Sort = active: 'name', direction: 'desc';
this.sort.active = sortState.active;
this.sort.direction = sortState.direction;
this.sort.sortChange.emit(sortState);

应该可以。 demo

要显示排序方向箭头,请添加下一个 css(解决方法)

th.mat-header-cell .mat-sort-header-container.mat-sort-header-sorted .mat-sort-header-arrow 
    opacity: 1 !important;
    transform: translateY(0) !important;

【讨论】:

请在您的代码中提供一些解释,以便以后的用户可以更轻松地遵循您的想法/代码。 我使用来自Nino 的排序和此处的 CSS 解决方法来让我以编程方式设置的排序显示箭头。 在 Angular 7 中,我只是设置了 this.sort = active: 'name', direction: 'desc' ;而且我不必添加任何 CSS 更改即可使箭头处于活动状态。 Nick Gallimore 也许你没有在正确的地方添加你的css?尝试将其添加到主全局 css 文件中(可以在 assets/css/...css 中) 如果不想使用!important,也可以用JS修复隐藏箭头:github.com/angular/components/issues/…【参考方案4】:

材料更新(使用 v7.3 测试):

@ViewChild(MatSort) matSort: MatSort;

private someMethod(): void 
  this.matSort.sort( id: 'columnName', start: 'asc', disableClear: false );

这也将更新mat-sort-header 的箭头,而无需任何解决方法

【讨论】:

【参考方案5】:

您也可以将 mat-table 排序属性绑定到您的组件变量。

正如@Andrew Seguin 所说:

<table matSort matSortActive="name" matSortDirection="asc">

如果您知道默认排序,这是设置默认排序的正确方法。

如果你从其他地方得到排序(在我的例子中是从查询字符串参数),你也可以这样做(排序箭头在这里完美工作):

sortDirection: 'name',  // this can be changed or filled in any time
sortProperty: 'asc',


<mat-table matSort [matSortActive]="sortProperty" [matSortDirection]="sortDirection">

【讨论】:

【参考方案6】:

有几个影响行为的因素。主要是使用MatTableDataSource 与DataSource 的手工衍生产品。因此,不同的解决方案可能在某些情况下有效,而在其他情况下则无效。

无论如何,这是一个旧的bug that's been well covered on GitHub。请为 GitHub 问题投票以吸引 Angular 团队的注意。

在该 GitHub 线程 (link) 上发布的最持久的解决方案是在应用排序顺序时调用以下方法:

public setSort(id: string, start?: 'asc' | 'desc') 
    start = start || 'asc';
    const matSort = this.dataSource.sort;
    const toState = 'active';
    const disableClear = false;

    //reset state so that start is the first sort direction that you will see
    matSort.sort( id: null, start, disableClear );
    matSort.sort( id, start, disableClear );

    //ugly hack
    (matSort.sortables.get(id) as MatSortHeader)._setAnimationTransitionState( toState );

【讨论】:

这应该是以编程方式更改排序的公认解决方案!太棒了,先生!【参考方案7】:

在我的情况下,排序不起作用,因为 ma​​tColumDef id 和 mat-cell var 不同

<ng-container matColumnDef="firstName">
   <th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-table-header">First Name</th>
  <td mat-cell *matCellDef="let item">  item.name</td>
</ng-container>

将 matColumnDef="firstName" 更改为 matColumnDef="name" 后与 item.name

    <ng-container matColumnDef="name">
   <th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-table-header">First Name</th>
  <td mat-cell *matCellDef="let item">  item.name</td>
</ng-container>

对我来说很好用

【讨论】:

【参考方案8】:

也许您尝试在页面的初始化时调用对名称和方向强制排序的函数?

     ngOnInit() 
    let defSort: Sort = ;
    defSort.direction = 'asc';
    defSort.active = 'name';
    this.sortData(defSort);
  

【讨论】:

这不是正确的解决方案。表已排序,但排序表头不知道,箭头(指示当前排序方向)不显示【参考方案9】:

我必须在加载时进行默认排序

const matSort =  id: defaultSort.name  as MatSortable;
this.sort.direction = defaultSort.sort === 'asc' ? '' : defaultSort.sort === 'desc' ? 'asc' : 'desc' as SortDirection;
this.sort.sort(matSort);

【讨论】:

【参考方案10】:

@Andrew Seguin 的答案(第一个和接受的答案)为我做了视觉技巧,但它没有 排序表格。

我的解决方案是使用@Andrew Seguin 提供的html 代码并自己调用sortData(sort: Sort) 方法,但是该怎么做呢? 正如documentation 中所指定的,,,Sort'' 是一个接口,它有两个属性,active 和 direction,并且接口必须看起来像这样:

export interface Sort 
   active:string //The id/name of the column being sorted
   direction:string //asc or dsc depending on the use case (The sort direction)

所以诀窍是调用ngOnInit中的sortData(sort: Sort)方法如下:

ngOnInit()
    //Do some nitialization
    this.sortData(active:'name', direction:'asc');


sortData(sort: Sort) 
    //Your sorting algorithm (see examples in documentation, link above and at the bottom)

HTML 代码与接受的答案相同;-) 希望这对任何人都有帮助, 亚历克斯

Documentation examples

【讨论】:

【参考方案11】:

要以编程方式添加排序,请将其添加到您的 css。

::ng-deep.mat-header-cell .mat-sort-header-container.mat-sort-header-sorted .mat-sort-header-arrow opacity: 1 !important;

【讨论】:

以上是关于Angular Material 中的默认排序 - 排序标题的主要内容,如果未能解决你的问题,请参考以下文章

Angular Material - 垫表排序行

Angular Material 表的问题 - 分页和排序

Angular Material 2 DataTable 使用嵌套对象排序

Angular Material表拖放列排序不起作用

Angular 9 - 删除 Angular Material Stepper 上的默认图标(创建)

Angular Material 2:多个 mat-table 排序仅适用于第一个表