首页 > 解决方案 > Clarity Datagrid 服务器端绑定自定义过滤器(代码优化)

问题描述

我正在尝试优化我的代码,该代码利用 Clarity 数据网格与服务器端绑定和一些自定义操作(例如,自定义过滤器,类似于Datagrid Enhancement: Filtering)和重新获取网格数据并进行额外调用的刷新按钮)。

这是当前的工作流程:

网格视图.html:

<button (click)="refresh()"
    global refresh
</button>
<clr-datagrid #dataGrid
              (clrDgRefresh)="datagridRefresh($event)">
  ...
    <clr-dg-row *ngFor="let dataItem of dataItems" [clrDgItem]="dataItem">
  ... 
   <clr-dg-footer>
      <clr-dg-pagination #pagination
                         [clrDgTotalItems]="total"
                         [hidden]="!total"
                         [clrDgPageSize]="DEFAULT_ITEMS_PER_PAGE">
...
      </clr-dg-pagination>
   </clr-dg-footer>
</clr-datagrid>

<cross-column-filter (changes)="filterChange($event);"
                          [filters]="filters">
</cross-column-filter>

gridView.component.ts:

dataItems: MyItem[];
readonly DEFAULT_ITEMS_PER_PAGE: number = 20;
private static readonly DEFAULT_START_INDEX: number = 0;

ngOnInit() {
  if (hasPredefinedFilters) {
     this.filters = this.predefinedFilters;
  }
  this.refreshSubscription = this.refreshSubject
        .subscribe(async (state: ClrDatagridStateInterface) => {
           await this.dispatchFilterRequestPromise(state);
        });
}

filterChange(filters: FilterItem[]) {
  this.filters = filters;
  // If total is changed to a smaller value when the current page is > 1, the clrDgRefresh event is fired which
  // leads to an additional request.
  // The following code solves that and ensures the current page is 1 when applying filter.
  if (this.state && this.state.page && this.state.page.from &&
        this.state.page.from > gridView.DEFAULT_START_INDEX) {
     $(".pagination-first").click();
  } else {
     this.refreshSubject.next(this.state);
  }
}


refresh() {
    this.additionalCalls();
    this.dispatchFilterRequestPromise(this.state);
}

additionalCalls() {
...
}


datagridRefresh(state: ClrDatagridStateInterface) {
  // Remember the last state to use it again when the global refresh button is clicked
  this.state = state;
  // clrDgRefresh event is fired on initial load and each filtering/paging operation.
  // It's not needed to fetch data on initial grid load because this is done when global refresh handler is attached.
  if (this.gridFirstRefresh) {
     this.gridFirstRefresh = false;
     this.refresh();
  } else {
     this.loading = true;
     this.refreshSubject.next(state);
  }
}

dispatchFilterRequestPromise = (state: ClrDatagridStateInterface): Promise<void> => {

  const requestFilters: MyFilterSpec = this.createRequestFilters(state);
  if (requestFilters) {
    this.dataService.getDataItems(ManagedObject.contextObject, requestFilters).then(result => {
        this.dataItems = result.dataItems;
        this.total = result.total;});
  } else {
     this.dataItems = [];
     this.total = 0;
     return null;
  }
};

标签: angularvmware-clarityclarity

解决方案


clrDgRefresh如果您开始使用此绑定,Clarity Datagrid 会自动调用。没有办法处理/避免这些调用。但是,如果我们在函数之前添加一个去抖动,datagridRefresh()那么我们可以使用一个标志来控制它。请查看此stackblitz 链接

其次, using也有一个问题clrDgRefresh,它不会立即在ngDestroy相应的组件上被销毁,因此它会在路由更改事件中多次调用处理程序。同样,可以通过与上述相同的解决方法来解决此问题(请参阅 stackblitz)


推荐阅读