Lad*_*dos 54 angular-material2 angular
我有一个带有排序标题的普通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>
Run Code Online (Sandbox Code Playgroud)
请注意 element.project.name
这是displayColumn配置:
displayedColumns = ['project.name', 'position', 'name', 'test', 'symbol'];
Run Code Online (Sandbox Code Playgroud)
更改'project.name'
到'project'
不工作,也不"project['name']"
我错过了什么?这甚至可能吗?
这是Stackblitz: Angular Material2 DataTable排序对象
编辑: 谢谢你的所有答案.我已经使用动态数据了.所以我不必为每个新的嵌套属性添加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();
}
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*ers 106
很难找到关于此的文档,但可以通过使用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;
}
Run Code Online (Sandbox Code Playgroud)
小智 19
您可以在组件中编写函数以从对象获取深层属性.然后在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'}
];
Run Code Online (Sandbox Code Playgroud)
并在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>
Run Code Online (Sandbox Code Playgroud)
我喜欢@Hieu_Nguyen 解决方案。我将补充一点,如果您像我一样在项目中使用 lodash,那么解决方案将转换为:
import * as _ from 'lodash';
this.dataSource.sortingDataAccessor = _.get;
Run Code Online (Sandbox Code Playgroud)
无需重新发明深层属性访问。
我使用了一种通用方法,它允许您使用 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);
}
Run Code Online (Sandbox Code Playgroud)
您只需要设置数据访问器
this.dataSource.sortingDataAccessor = pathDataAccessor;
Run Code Online (Sandbox Code Playgroud)
小智 7
只要为字段使用点符号,给出的答案甚至可以缩短,不需要切换。
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;
}
Run Code Online (Sandbox Code Playgroud)