Привязка на стороне сервера Clarity Datagrid с настраиваемым фильтром (оптимизация кода)

Я пытаюсь оптимизировать свой код, который использует сетку данных Clarity с привязкой на стороне сервера и некоторыми настраиваемыми действиями (например, настраиваемый фильтр, аналогичный Datagrid Enhancement: Filtering) и кнопку обновления, которая обновляет данные сетки и выполняет дополнительные вызовы).

Это текущий рабочий процесс:

  • Начальная нагрузка

    • datagridRefresh ()

      • обновить ()

        • additionalCalls()
        • dispatchFilterRequestPromise ()
  • Пользовательская кнопка обновления

    • обновить ()

      • additionalCalls()
      • dispatchFilterRequestPromise ()
  • Paging
    • datagridRefresh()
      • dispatchFilterRequestPromise()
  • Пользовательская фильтрация

    • filterChange ()

      • $(".pagination-first").click()
        • datagridRefresh()
          • dispatchFilterRequestPromise()
      • (или) dispatchFilterRequestPromise ()

gridView.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 (т.е. datagridRefresh), чтобы различать начальную загрузку и последующие вызовы. Я вижу, что есть ошибка, связанная с тем, чтобы не запускать clrDgRefresh при начальной загрузке (clr-datagrid не должен вызывать clr-dgRefresh при уничтожении / инициализации). Если ошибка устранена, я могу переместить код внутри этого флага в событие onInit, но я вижу, что проблема была открыта 2 года назад, и не уверен, есть ли в ней какой-либо прогресс.

  • Другой вопрос связан с запуском обновления пользовательского фильтра (например, filterChange ()).

  • Я задавался вопросом, может ли привязка на стороне клиента к настраиваемому пейджеру сделать код более понятным, чем текущий подход.


person user1781328    schedule 17.09.2019    source источник


Ответы (1)


Clarity Datagrid автоматически вызывает clrDgRefresh, если вы начинаете использовать эту привязку. Невозможно обработать / избежать этих вызовов. Однако, если мы добавим отладку перед функцией datagridRefresh(), тогда мы сможем управлять им с помощью флага. Просмотрите эту ссылку на stackblitz

Во-вторых, есть еще одна проблема с использованием clrDgRefresh, она не удаляется сразу после ngDestroy соответствующего компонента и, следовательно, он вызывает обработчик несколько раз при изменении маршрута. Опять же, эту проблему можно решить с помощью того же обходного пути, который упоминался выше (см. Stackblitz).

person Idris Rampurawala    schedule 15.07.2020