각도 재료 2 중첩된 객체를 사용한 데이터 테이블 정렬
나는 정렬 헤더가 있는 일반적인 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:각도 재료2 데이터 테이블 객체 정렬
편집: 답변해 주셔서 감사합니다.동적 데이터로 이미 작동하고 있습니다.따라서 새로 중첩된 모든 속성에 대해 스위치 문을 추가할 필요가 없습니다.
다음은 제 솔루션입니다. (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();
}
}
이에 대한 설명서를 찾기 어려웠지만, 사용하면 가능합니다.sortingDataAccessor그리고 스위치 문.예:
@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;
}
구성 요소에 함수를 작성하여 개체로부터 깊은 속성을 얻을 수 있습니다.그럼 다음에 사용하세요.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>
필드에 도트 표기법을 사용하는 한, 주어진 답은 단축할 수도 있고 전환할 필요도 없습니다.
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;
}
나는 당신이 dot.separated를 사용할 수 있는 일반적인 방법을 사용합니다.와의 길.mat-sort-header또는matColumnDef경로에 의해 지시된 속성을 찾을 수 없는 경우 정의되지 않은 속성을 자동으로 반환하지 않습니다.
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;
저는 @Hieu_Nguyen 솔루션을 좋아합니다.프로젝트에서 저처럼 lodash를 사용하면 솔루션이 다음과 같이 해석됩니다.
import * as _ from 'lodash';
this.dataSource.sortingDataAccessor = _.get;
심층적인 자산 액세스를 재창조할 필요가 없습니다.
데이터 소스에 추가하기만 하면 중첩된 개체에 액세스할 수 있습니다.
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];
};
여러 중첩된 개체 수준에 맞게 사용자 지정했습니다.
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;
};
또 다른 대안은, 아무도 여기에 버리지 않은, 먼저 기둥을 평평하게 만드는 것입니다.
yourData.map((d) =>
d.flattenedName = d.project && d.project.name ?
d.project.name :
'Not Specified');
this.dataSource = new MatTableDataSource(yourData);
각각의 장단점을 가진 또 다른 대안일 뿐입니다!
중첩 객체 정렬과 같이 일부 확장 기능이 있는 Angular 재료 테이블을 사용하려면 https://github.com/mikelgo/ngx-mat-table-extensions/blob/master/libs/ngx-mat-table/README.md 을 참조하십시오.
이 lib를 만든 이유는 매트 테이블의 일부 기능이 상자 밖에 없기 때문입니다.
고급 정렬은 @Hieu Nguyen이 제안한 답변과 비슷하지만 대문자와 소문자로 적절하게 정렬되도록 약간 확장되었습니다.
요소별로 정렬하려고 합니다['project.name '].분명히 원소는 그러한 속성을 가지고 있지 않습니다.
MatTableData 소스를 확장하고 중첩된 개체 속성별 정렬을 지원하는 사용자 지정 데이터 소스를 쉽게 만들 수 있어야 합니다.사용자 지정 소스 사용에 대한 material.angular.io 문서의 예제를 확인하십시오.
저도 같은 문제가 있었습니다. 처음에 몇 가지 오류가 발생한 제안을 테스트함으로써 "스위치(속성)"를 추가하여 해결할 수 있었습니다.
this.dataSource.sortingDataAccessor =(item, property) => {
switch (property) {
case 'project.name': return item.project.name;
default: return item[property];
}
};
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;
}
테이블 열이 제대로 정렬되지 않아 데이터 작업을 위해 답변 중 하나를 수정했습니다.
function pathDataAccessor(item: any, path: string): any {
return (item: any, path: string): any => {
return path.split(".").reduce((accumulator: any, key: string) => {
let returnValue;
if (accumulator) {
returnValue = accumulator[key];
} else {
returnValue = undefined;
}
if (typeof returnValue === "string") {
returnValue = returnValue.trim().toLocaleLowerCase();
}
return returnValue;
}, item);
};
}
저는 명확한 솔루션을 찾고 모든 입력 데이터에 대해 작동합니다.
this.dataSource.sortingDataAccessor = (obj: any, property: string) => property.split('.').reduce((o, p) => o && o[p], obj);
this.dataSource.sort = this.sort;
HTML 파일에서 중첩된 개체를 mat-sort-header로 설정해야 합니다.EX:mat-sort-header="User.Name"
<ng-container matColumnDef="UserName">
<th mat-header-cell *matHeaderCellDef mat-sort-header="User.Name">User</th>
<td mat-cell *matCellDef="let row">{{ row.User.Name}}</td>
</ng-container>
설명:첫 번째 단계: 데이터 소스를 설정합니다.섹션: 일반 정렬 데이터 가속기를 설정합니다.셋째: 데이터 소스에 대한 정렬을 호출합니다.
this.dataSource = new MatTableDataSource(project.ActivityLog.items);
setTimeout(() => {
this.dataSource.sortingDataAccessor = (obj: any, property: string) => property.split('.').reduce((o, p) => o && o[p], obj);
this.dataSource.sort = this.sort;
})
}
데이터에 아래 예제와 같은 내부 개체가 포함된 경우
myData = [ {service: 'SRS',
team: {id: 'T1', name: 'Blasters'},
rank: 23,
.....
},
{ service: 'COC',
team: {id: 'T2', name: 'Strikers'},
rank: 7,
.....
},
......
]
그러면 사용자 정의 정렬 기능을 사용할 수 있습니다.
<table mat-table [dataSource]="myData" #outersort="matSort" matSort>
<ng-container matColumnDef="service">
<th mat-header-cell *matHeaderCellDef mat-sort-header>SERVICE</th>
<td mat-cell *matCellDef="let element">
{{ element.service }}
</td>
</ng-container>
<ng-container matColumnDef="team.name">
<th mat-header-cell *matHeaderCellDef mat-sort-header>TEAM</th>
<td mat-cell *matCellDef="let element">
{{ element.team.name }}
</td>
</ng-container>
.....
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
표시된 열은 다음과 같이 중첩된 개체를 나타내야 합니다.
displayedColumns = ['service','team.name', 'rank']
및 ts 파일
@ViewChild(MatSort) MySort: MatSort;
.....
this.dataSource = new MatTableDataSource(myData);
this.dataSource.sortingDataAccessor = (item, property) => {
return eval('item.'+property);
};
this.dataSource.sort = MySort;
.....
언급URL : https://stackoverflow.com/questions/48891174/angular-material-2-datatable-sorting-with-nested-objects
'programing' 카테고리의 다른 글
| Xcode가 시작되지 않습니다. 'Xcode 확인 중...'에 계속 표시됩니다. (0) | 2023.05.02 |
|---|---|
| GCC 사용 시 "Xcode/iOS 라이센스에 동의하려면 관리자 권한이 필요합니다. sudo를 통해 root로 다시 실행하십시오." (0) | 2023.05.02 |
| 신규 대신 할당 사용 (0) | 2023.05.02 |
| 판다 파이썬에서 문자열을 날짜 시간 형식으로 변환하는 방법은 무엇입니까? (0) | 2023.05.02 |
| 최신 버전의 OS X(요세미티 또는 엘 캐피탄)를 설치한 후 "pg_tblspc"가 없습니다. (0) | 2023.05.02 |