Tengo una tabla de datos de material angular 2 normal con encabezados de clasificación. Todos los tipos son encabezados que funcionan bien. Excepto el que tiene un objeto como valor. Estos no ordenan en absoluto.
Por ejemplo:
<!-- 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> tenga en cuenta el element.project.name
Aquí está la configuración de displayColumn:
displayedColumns = ['project.name', 'position', 'name', 'test', 'symbol']; Cambiar 'project.name' a 'project' no funciona ni "project['name']"
¿Qué me estoy perdiendo? ¿Es esto posible?
Aquí hay un Stackblitz: Angular Material2 DataTable ordenar objetos
Editar: Gracias por todas sus respuestas. Ya lo tengo trabajando con datos dinámicos. Por lo tanto, no tengo que agregar una declaración de cambio para cada nueva propiedad anidada.
Aquí está mi solución: (No es necesario crear un nuevo DataSource que amplíe MatTableDataSource)
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(); } }Fue difícil encontrar documentación sobre esto, pero es posible usando sortingDataAccessor y una declaración de cambio. Por ejemplo:
@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; }Puede escribir una función en el componente para obtener una propiedad profunda del objeto. Luego utilícelo en dataSource.sortingDataAccessor como a continuación
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'} ];y en 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>La respuesta dada puede incluso acortarse, no se requiere cambiar, siempre que use la notación de puntos para los campos.
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; }