我有一个带有排序标题的普通Angular Material 2 DataTable。 所有排序都是标题工作正常。除了具有对象作为值的那个。 这些根本不排序。
例如:
<!-- Project Column - This should sort!-->
<ng-container matColumnDef="project.name">
<mat-header-cell *matHeaderCellDef mat-sort-header> Project Name </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.project.name}} </mat-cell>
</ng-container>
请注意element.project.name
这是displayColumn配置:
displayedColumns = ['project.name', 'position', 'name', 'test', 'symbol'];
将'project.name'
更改为'project'
不起作用,也不会"project['name']"
我错过了什么?这甚至可能吗?
这是Stackblitz: Angular Material2 DataTable sort objects
修改 谢谢你的所有答案。 我已经使用动态数据了。所以我不必为每个新的嵌套属性添加一个switch语句。
这是我的解决方案:(创建一个扩展MatTableDataSource的新DataSource不是必需的)
export class NestedObjectsDataSource extends MatTableDataSource<MyObjectType> {
sortingDataAccessor: ((data: WorkingHours, sortHeaderId: string) => string | number) =
(data: WorkingHours, sortHeaderId: string): string | number => {
let value = null;
if (sortHeaderId.indexOf('.') !== -1) {
const ids = sortHeaderId.split('.');
value = data[ids[0]][ids[1]];
} else {
value = data[sortHeaderId];
}
return _isNumberValue(value) ? Number(value) : value;
}
constructor() {
super();
}
}
答案 0 :(得分:69)
很难找到相关文档,但可以使用sortingDataAccessor
和switch语句。例如:
@ViewChild(MatSort) sort: MatSort;
ngOnInit() {
this.dataSource = new MatTableDataSource(yourData);
this.dataSource.sortingDataAccessor = (item, property) => {
switch(property) {
case 'project.name': return item.project.name;
default: return item[property];
}
};
this.dataSource.sort = sort;
}
答案 1 :(得分:17)
您可以在组件中编写一个函数来从对象获取深层属性。然后在dataSource.sortingDataAccessor
中使用它,如下所示
getProperty = (obj, path) => (
path.split('.').reduce((o, p) => o && o[p], obj)
)
ngOnInit() {
this.dataSource = new MatTableDataSource(yourData);
this.dataSource.sortingDataAccessor = (obj, property) => this.getProperty(obj, property);
this.dataSource.sort = sort;
}
columnDefs = [
{name: 'project.name', title: 'Project Name'},
{name: 'position', title: 'Position'},
{name: 'name', title: 'Name'},
{name: 'test', title: 'Test'},
{name: 'symbol', title: 'Symbol'}
];
并在html中
<ng-container *ngFor="let col of columnDefs" [matColumnDef]="col.name">
<mat-header-cell *matHeaderCellDef>{{ col.title }}</mat-header-cell>
<mat-cell *matCellDef="let row">
{{ getProperty(row, col.name) }}
</mat-cell>
</ng-container>
答案 2 :(得分:4)
给出的答案甚至可以缩短,无需切换,只要您对字段使用点符号即可。
ngOnInit() {
this.dataSource = new MatTableDataSource(yourData);
this.dataSource.sortingDataAccessor = (item, property) => {
if (property.includes('.')) return property.split('.').reduce((o,i)=>o[i], item)
return item[property];
};
this.dataSource.sort = sort;
}
答案 3 :(得分:2)
我使用一种通用方法,该方法允许您将dot.seperated.path与mat-sort-header
或matColumnDef
一起使用。如果找不到路径所指示的属性,则无法以静默方式返回undefined。
function pathDataAccessor(item: any, path: string): any {
return path.split('.')
.reduce((accumulator: any, key: string) => {
return accumulator ? accumulator[key] : undefined;
}, item);
}
您只需要设置数据访问器
this.dataSource.sortingDataAccessor = pathDataAccessor;
答案 4 :(得分:1)
我为多个嵌套对象级别定制。
this.dataSource.sortingDataAccessor =
(data: any, sortHeaderId: string): string | number => {
let value = null;
if (sortHeaderId.includes('.')) {
const ids = sortHeaderId.split('.');
value = data;
ids.forEach(function (x) {
value = value? value[x]: null;
});
} else {
value = data[sortHeaderId];
}
return _isNumberValue(value) ? Number(value) : value;
};
答案 5 :(得分:1)
只需将其添加到您的数据源中,您就可以访问嵌套对象
this.dataSource.sortingDataAccessor = (item, property) => {
// Split '.' to allow accessing property of nested object
if (property.includes('.')) {
const accessor = property.split('.');
let value: any = item;
accessor.forEach((a) => {
value = value[a];
});
return value;
}
// Access as normal
return item[property];
};
答案 6 :(得分:0)
它试图按元素排序[&#39; project.name&#39;]。显然元素没有这样的属性。
创建一个扩展MatTableDatasource并支持按嵌套对象属性排序的自定义数据源应该很容易。查看关于使用自定义源的material.angular.io文档中的示例。
答案 7 :(得分:0)
我有同样的问题,通过测试第一个命题我有一些错误,我可以通过添加&#34;开关(属性)&#34;
来修复它Code week_Num week_day return
234234 1 1 0
423443 1 2 0
234234 1 3 0
996434 1 4 0
444234 1 5 0
234234 1 6 0
234234 1 7 0
423423 2 1 0
234234 2 2 1
686433 2 3 2
234234 2 4 0
225257 2 5 3
234234 2 6 0
and so on...
答案 8 :(得分:0)
另一种选择是,没有人扔在这里,先将色谱柱弄平...
yourData.map((d) =>
d.flattenedName = d.project && d.project.name ?
d.project.name :
'Not Specified');
this.dataSource = new MatTableDataSource(yourData);
只是另一种选择,各有利弊!
答案 9 :(得分:0)
我喜欢@Hieu_Nguyen解决方案。我要补充一点,如果像我一样在项目中使用lodash,那么解决方案将转换为:
import * as _ from 'lodash';
this.dataSource.sortingDataAccessor = _.get;
无需重新构造深度属性访问权限。
答案 10 :(得分:0)
使用 MatTableDataSource 检查完整的MatSort问题解决方案
以HTML
<ng-container matColumnDef="createdDate" @bounceInLeft>
<th mat-header-cell *matHeaderCellDef mat-sort-header class="date"> Created date
</th>
<td mat-cell *matCellDef="let element" class="date"> {{element.createdDate
| date :'mediumDate'}} </td>
</ng-container>
<ng-container matColumnDef="group.name">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="type"> Group </th>
<td mat-cell *matCellDef="let element" class="type"> {{element.group.name}} </td>
</ng-container>
@ViewChild(MatSort, { static: true }) sort: MatSort;
ngOnInit() {
this.dataSource = new MatTableDataSource(yourData);
this.dataSource.sortingDataAccessor = (item, property) => {
switch(property) {
case 'project.name': return item.project.name;
default: return item[property];
}
};
this.dataSource.sort = sort;
}
答案 11 :(得分:0)
如果你想要一个带有一些扩展功能的 Angular 材质表,比如嵌套对象的排序,请查看 https://github.com/mikelgo/ngx-mat-table-extensions/blob/master/libs/ngx-mat-table/README.md 。
我创建这个库是因为我缺少一些 mat-table 开箱即用的功能。
高级排序类似于@Hieu Nguyen 建议的答案,但稍微扩展为也可以按大小写字母进行适当排序。