神经树网格分层过滤器或排序

问题描述

我在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);}

对于排序,您可以执行类似的操作。