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 提供更新的示例
【讨论】:
此方法仅适用于第一次。更改表的数据源后,我尝试重新设置matSortActive
和matSortDirection
,但未显示小箭头
样本好像不行了,我做了一个新的:stackblitz.com/edit/angular-defaultsort?file=src/app/…
您可以使用this solution 触发排序并修复隐藏箭头错误。我正在使用没有数据源的 mat-sort-header,这是唯一有效的修复方法。
@GilEpshtain 来解决这个问题,请在下面使用@Aman Madiiarbekov 的答案。
您好,如果我的表格实现了分页,如何保证active
和direction
的参数能延续到下一页?【参考方案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】:在我的情况下,排序不起作用,因为 matColumDef 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 2 DataTable 使用嵌套对象排序