Как использовать быстрый фильтр с серверной / бесконечной строковой моделью?

Согласно документации: Быстрый фильтр, быстрый фильтр работает с clientSide строчной моделью.

Мы используем модель serverSide строк для ag-grid и у нас есть требование использовать быстрый фильтр с данными, которые у нас есть на клиенте - в блоках кеша сетки.

Я хотя и использую фильтрующий канал с [rowData]="myRowData", но с этой строковой моделью я не получаю никаких данных от myRowData.

Например, если вы посмотрите на эту массивную модель строк на стороне сервера - быстрый фильтр , Я назначил [rowData]="rowData" в разметке и инициализировал его как [].

После загрузки начального фрагмента с сервера я предполагал, что данные блока кеша должны быть доступны с ним, так что, используя угловой канал, я мог бы отфильтровать данные на стороне клиента (имитируя быстрый фильтр с serverSide строчной моделью). Что-то вроде [rowData]="rowData | filter: filterText" - вроде того, что мы делали раньше в angularjs

Но я боюсь, что данные кеша недоступны с rowData.

Как мы можем как-то использовать Быстрый фильтр с ag-сеткой, имеющей serverSide строчную модель?


person Paritosh    schedule 29.11.2018    source источник
comment
предоставьте короткий образец, пожалуйста, для обходного пути   -  person un.spike    schedule 30.11.2018
comment
обновил вопрос со ссылкой на планку   -  person Paritosh    schedule 30.11.2018
comment
Я не могу сказать достаточно спасибо за этот вопрос. Это именно то, что я искал, и данный ответ решил проблему и сэкономил мне много часов работы и отладки. Это сообщество является лучшим для разработчиков, которые любят часто попадать в тройку.   -  person omostan    schedule 18.09.2020


Ответы (2)


Я бы сказал, что это была непростая задача.

Но вот как это можно решить:

  1. Как вы уже упоминали, quickFilter - это clientSide функция типа модели
  2. Но никто не отменял setFilterModel способ использования
    # P3 #

Во-первых, setFilterModel не может работать с виртуальными данными (мы должны определить column, особенно для quickFilter логики)

{
    field:'-', would be used as a reference
    hide:true, - hide in grid data
    lockVisible:true, - disable visibility changing via menu
    filter:"agTextColumnFilter", - require for setFilterModel
    filterParams:{
      newRowsAction: "keep"
    }
},

Затем нам нужно создать обходной путь для filterModel в datasource

getRows: function(params) {
    setTimeout(function() {
        var dataAfterSortingAndFiltering = sortAndFilter(data, params.sortModel, params.filterModel);
        var rowsThisPage = dataAfterSortingAndFiltering.slice(params.startRow, params.endRow);
        var lastRow = -1;
        if (dataAfterSortingAndFiltering.length <= params.endRow) {
            lastRow = dataAfterSortingAndFiltering.length;
        }
        params.successCallback(rowsThisPage, lastRow);
    }, 3000);
}

function sortAndFilter(allOfTheData, sortModel, filterModel) {
  return sortData(sortModel, filterData(filterModel, allOfTheData));
}
function sortData(sortModel, data) {
  ... sort logic here (doesn't matter for now) ...
}

Теперь о quickFilter логике, мы определили для нее dummy столбец и вот как его следует использовать:

setFilterModel примет только существующее имя столбца ("-" в нашем случае)

и с ограниченными свойствами объекта: но мы будем использовать filter (как в реальных случаях)

applyFilter(){
    this.gridApi.setFilterModel({"-":{filter: this.filterText}})
}

и последняя точка реализации - filterData функция

function filterData(filterModel, data) {
  let filterPresent = filterModel && Object.keys(filterModel).length > 0;
  if (!filterPresent) { - if filter model is empty - skip it
    return data;
  }
  data = data.filter(i=>{
    if(Object.keys(i).some(k => i[k] && i[k].toString().toLowerCase().includes(filterModel['-'].filter)))
      return i;
  })
  return data;
}

Каждый объект будет исследован, и если какое-либо свойство содержит quickFilter значение - оно будет в результате

Более того, как только вы выйдете за пределы существующего диапазона (случай бесконечной прокрутки), запрошенные данные будут отфильтрованы этим свойством.

* не уверен в проверке дублированных данных по запросу

Мой образец

Ваш измененный образец

person un.spike    schedule 01.12.2018
comment
Спасибо за ваши усилия! Que: Итак, когда я использую setFilterModel, он все равно вызывает dataSource.getRows и вызывает сервер для получения данных. Это просто фильтр, который мы применяем на стороне клиента. Я прав? Если это так, моя цель - просто избежать отключения сервера, применив фильтр к любым данным, доступным на клиенте. - person Paritosh; 03.12.2018
comment
Кажется, что (в любом случае о поездке на сервер) я пытался найти способ получить данные из кеша, но не понял. более того, он не запрашивает весь счет (как был загружен) и работает только с первым блоком. * поэтому я полагаю, что ag-grid на данный момент не предоставляет возможности обработать ваш случай, потому что даже если вы попытаетесь обновить данные напрямую, он выдаст предупреждение о том, что для модели на стороне службы метод setRowData ограничен. - person un.spike; 03.12.2018
comment
Этот ответ направил меня в правильном направлении к решению этой проблемы и сэкономил много часов работы и отладки. Супер объяснение и отличный гид. Спасибо за участие в этом очень важном сообществе разработчиков. Метод filterData немного сложен при работе с более чем одним столбцом с разными типами данных. Я надеюсь найти время, чтобы создать для этого демо-плункер и поделиться им здесь с другими. - person omostan; 18.09.2020

В конце концов я нашел статью поддержки ag-Grid:

https://ag-grid.zendesk.com/hc/en-us/articles/360020488612?input_string=serverside+quick+filter

Его первый пример предлагает отредактировать getRows вашего ServerSideDatasource, чтобы добавить к params.request новый ключ.

Например, вы можете сделать что-то вроде следующего:

const customParams = {};
customParams.quickFilterValue = 'someQuery';

In onGridReady:

const datasource = createServerSideDatasource(server, customParams);
event.api.setServerSideDatasource(datasource)
/**
 *
 * @param {object} server
 * @param {object} customParams
 * @returns {object}
 */
export function createServerSideDatasource(server, customParams) {
  // https://www.ag-grid.com/javascript-grid-server-side-model-datasource/

  return {
    getRows: function (params) {
      params.request.customParams = customParams // Our backend will need to handle this custom 'customParams' key that the frontend attaches to the request (which itself will contain a quickFilterValue key and maybe others).

      const response = server.getData(params.request);

      if (response.success) {
        params.successCallback(response.rows, response.lastRow);
      } else {
        params.failCallback();
      }

    },
  };
}
person Ryan    schedule 16.12.2020