问题描述
我在Nebular v6.1.0中使用angular 9 我有一个显示在界面中的元素列表。为此,我使用了星形TreeGridComponent。 只要是字符串或数字之类的基本数据类型,我的对象的每个属性都可以进行过滤和排序而不会出现问题。 但是,我的对象还包含另一个对象类型的复杂数据类型。尽管可以毫无问题地显示这些属性,但似乎无法对其进行过滤。 我希望我的意思是可以理解的。 这是一个小例子:
import { Component } from '@angular/core';
import { NbGetters,NbTreeGridDataSource,NbTreeGridDataSourceBuilder } from '@nebular/theme';
interface FSEntry {
name: string;
myObject: MyObject;
}
interface MyObject {
myObjectName: string;
}
@Component({
template: `
<nb-card>
<nb-card-body>
<table [nbTreeGrid]="source" nbSort (sort)="changeSort($event)">
<tr nbTreeGridHeaderRow *nbTreeGridHeaderRowDef="allColumns"></tr>
<tr nbTreeGridRow *nbTreeGridRowDef="let row; columns: allColumns"></tr>
<!-- this row is sortable -->
<ng-container nbTreeGridColumnDef="name">
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef [nbSortHeader]="getDirection('name')">Name</th>
<td nbTreeGridCell *nbTreeGridCellDef="let row">
row.data.name
</td>
</ng-container>
<!-- this row is NOT sortable -->
<ng-container nbTreeGridColumnDef="myObjectName">
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef [nbSortHeader]="getDirection('myObjectName')">MyObjectName</th>
<td nbTreeGridCell *nbTreeGridCellDef="let row">
row.data.myObject.myObjectName
</td>
</ng-container>
</table>
</nb-card-body>
</nb-card>
`,styleUrls: ['./tree-grid-shared.scss'],})
export class TreeGridComponent {
defaultColumns = [ 'name','myObjectName' ];
allColumns = [ ...this.defaultColumns ];
source: NbTreeGridDataSource<FSEntry>;
constructor(dataSourceBuilder: NbTreeGridDataSourceBuilder<FSEntry>) {
const getters: NbGetters<FSEntry,FSEntry> = {
dataGetter: (node: FSEntry) => node,childrenGetter: (node: FSEntry) => node.childEntries || undefined,expandedGetter: (node: FSEntry) => !!node.expanded,};
this.source = dataSourceBuilder.create(this.data,getters);
}
getDirection(column: string): NbSortDirection {
if (column === this.sortColumn) {
return this.sortDirection;
}
return NbSortDirection.NONE;
}
changeSort(sortRequest: NbSortRequest): void {
this.dataSource.sort(sortRequest);
this.sortColumn = sortRequest.column;
this.sortDirection = sortRequest.direction;
}
private data: FSEntry[] = [
{
name: 'name 1',myObject: {
myObjectName: 'myObjectName 1'
}
},{
name: 'name 2',myObject: {
myObjectName: 'myObjectName 2'
}
}
];
}
使用此代码可以对name
-行的升序或降序进行排序,但不能对myObjectName
-行的行进行排序。
是否可以在不将属性从MyObject
移至FSEntry
的情况下解决此问题?
解决方法
也许这对你有帮助?创建一个扩展 NbTreeGridFilterService 的自定义类
import { NbTreeGridFilterService } from '@nebular/theme';
export class CustomTreeGridFilterService<T> extends NbTreeGridFilterService<T> {
protected filterPredicate(data: T,searchQuery: string): boolean {
const preparedQuery = searchQuery.trim().toLocaleLowerCase();
for (const val of Object.values(data)) {
const prepVal = this.prepValue(val);
const preparedVal = `${prepVal}`.trim().toLocaleLowerCase();
if (preparedVal.includes(preparedQuery)) {
return true;
}
}
return false;
}
prepValue(value): string[] {
const x = [];
const isObject = typeof value === 'object' && value !== null;
if (!isObject) {
x.push(value);
} else {
for (const val of Object.values(value)) {
x.push(this.prepValue(val));
}
}
return x;
}
}
然后在你的组件中像这样使用它
constructor() {
const filterService = new CustomTreeGridFilterService<Client>();
const sortService = new NbTreeGridSortService<Client>();
const treeGridService = new NbTreeGridService<Client>();
const treeGridDataService = new NbTreeGridDataService<Client>();
const dataSourceBuilder = new NbTreeGridDataSourceBuilder<Client>(filterService,sortService,treeGridService,treeGridDataService);}
对于排序,您可以执行类似的操作。