0

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

这是当前的工作流程:

  • 初始负载

    • 数据网格刷新()

      • 刷新()

        • 附加呼叫()
        • dispatchFilterRequestPromise()
  • 自定义刷新按钮

    • 刷新()

      • 附加呼叫()
      • dispatchFilterRequestPromise()
  • 寻呼
    • 数据网格刷新()
      • dispatchFilterRequestPromise()
  • 自定义过滤

    • 过滤器更改()

      • $(".pagination-first").click()
        • 数据网格刷新()
          • dispatchFilterRequestPromise()
      • (或) dispatchFilterRequestPromise()

网格视图.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;
  }
};
  • 我在 clrDgRefresh(ie,datagridRefresh) 中有一个标志来区分初始加载和后续调用。我看到有一个与避免在初始加载时触发 clrDgRefresh 相关的错误(clr-datagrid 在被销毁/初始化时不应调用 clr-dgRefresh)。如果错误得到解决,我可以将该标志内的代码移动到 onInit 事件,但我看到该问题已在 2 年前打开,不确定是否有任何进展。

  • 另一个问题与触发自定义过滤器更新(即filterChange())有关。

  • 我想知道使用自定义寻呼机进行客户端绑定是否会使代码看起来比当前方法更清晰。

4

1 回答 1

1

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

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

于 2020-07-15T07:40:58.310 回答