Фильтр AngularJS ng-grid - формат filterText

Я использую AngularJS ng-grid (v2.0.7 v2.0.8), и я хотел бы понять синтаксис поля filterText в API.

В частности, я хотел бы знать, как фильтровать определенные столбцы или столбцы и фильтровать одну или несколько записей в столбце.

Существует много вопросов о переполнении стека с тегами ng-grid и filter, и, хотя они полезны, в настоящее время отсутствует полный обзор формата filterText.

2 ответа

Решение

На момент написания этой статьи не было краткого описания того, как вообще построить строку 'filterText'. Изучив код ng-grid.js и сделав некоторые предположения, я обнаружил, что "filterText" гораздо более мощный и выразительный, чем предполагает текущая документация.

Пример настройки

Чтобы настроить ответ, сначала рассмотрите сетку со следующим определением, расположенную в некотором контроллере:

  $scope.pricing_data = data['records'];

  $scope.gridOptions = { 
    data: 'pricing_data',
    columnDefs: [
      { field: 'ticker', displayName: 'Ticker' },
      { field: 'date',   displayName: 'Date'   },
      { field: 'close',  displayName: 'Close'  },
      { field: 'volume', displayName: 'Volume' }
    ],
    filterOptions: {filterText: '', useExternalFilter: false},
    showFilter: true
  };

Объект в data['records'] может быть каким-то json-объектом, отправленным из серверной части. Пример таблицы может выглядеть так:

нефильтрованный стол

В существующем состоянии filterText является пустым, поэтому все записи представлены.

Морковь внизу в правом верхнем углу сетки видна, потому что showFilter имеет значение true. Нажатие на морковь внизу показывает ввод, связанный с переменной filterText. В этом обсуждении я покажу некоторые результаты, используя этот раскрывающийся список, но обычно вы можете напрямую назначить filterText в коде вашего контроллера. Раскрывающийся список выглядит так:

Виджет showFilter привязан к filterText

Поиск по всем полям в сетке

По умолчанию filterText выполняет регулярное выражение для каждой ячейки в сетке. Ввод символа "а" выбирает все записи, которые имеют символ "а" в любой записи (или столбце) этой записи. Нажатие на "ab" выбирает все записи, которые имеют последовательность символов "ab" в любой записи этой записи. В зависимости от ваших требований это поведение может быть вполне подходящим. Однако для больших наборов данных обычно требуется фильтровать по столбцам, а не по всей сетке, из-за характера данных (например, выбор тикера цены) и из-за высокой стоимости поиска по всей сетке.

Поиск по столбцу

Чтобы найти строку или регулярное выражение только в одном столбце, синтаксис filterText имеет следующий вид:

filterText = '<displayName>:<literal>'

Например,

фильтр первого столбца

Здесь displayName 'Date' (не используйте значение поля, вы должны использовать displayName) сопровождается двоеточием ':' и затем частичной строкой. В результате выбираются только три записи, связанные с 30 октября.

Давайте расширим поиск. Для поиска 30 октября или 31 октября синтаксис

filterText = '<displayName>:<literal 1>|<literal 2>|...'

где труба '|' отделяет каждую строку частичной. Вы можете связать вместе сколько угодно. Фильтр нескольких дат может выглядеть так:

введите описание изображения здесь

Ясно, что выбор является или по природе. Однако мой пример не очень хорош, потому что тикеры и даты имеют непересекающиеся символы. Поэтому вы можете либо довериться мне, что ищется только столбец "Дата", либо настроить собственный пример. (Или, что еще лучше, прочитайте функцию buildSearchConditions() в ng-grid, это довольно ясно).

Поиск записей в нескольких столбцах

Поиск по нескольким столбцам требует только синтаксического расширения поиска в столбце. Этот синтаксис:

filterText = '<displayName 1>:<lit 1>[|<lit 2>|..];<displayName 2>:<lit a>[|<lit b>|..][;..]'

Оперативным лексическим элементом является точка с запятой ';' который отделяет каждый столбец displayName.

Продолжая этот пример, давайте поищем nyt или nvda 30 октября или 31 октября. Это выглядит так:

многоколонный фильтр 1

Логически, фильтр ищет (вдоль Тикера nyt ИЛИ nvda) И (вдоль Даты 10-30 ИЛИ 10-31).

Обновления сетки

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

Когда контроллер angular-js, работающий совместно с бэкэндом, обновляет данные сетки, тогда обновленные данные пропускаются через фильтр. Это прекрасный результат, в действительности фильтр сохраняется.

Известная ошибка - Очистить

На момент написания этой статьи недавно было исправлено известная ошибка, когда очистка filterText почти или действительно приводит к зависанию браузера. Вот отчет, за которым я следил: ng-grid проблема 777. Исправление было объединено после проблемы ng-grid 848. Я могу точно подтвердить, что вижу низкую производительность, когда фильтр, примененный к большому набору данных, очищен. Я еще не проверял исправление.

ОБНОВИТЬ

Я только что нашел время для установки ng-grid 2.0.8. Ясная проблема исправлена. Работает отлично.


нг-сетка 3.0

ng-grid 3.0 сейчас на чертежной доске. В ng-grid 2.0 так много хорошего, но, как и любой новый код, несколько переписываний помогают. Я призываю разработчиков ng-grid сохранить функции фильтра, которые они уже включили, и, возможно, расширить производительность или диапазон.

Основываясь на ответе JayInNyc, я сделал несколько вещей, чтобы пользователю было проще пользоваться, а не следовать этому синтаксису. Я в основном наблюдаю за любыми полями, по которым я хочу фильтровать. В этом случае у меня есть поле ввода для имени и города.

$scope.filterOptions = {
    filterText: ''
};
$scope.filterName = '';
$scope.filterCity = '';

$scope.$watch('filterName', function (value) {

    setFilterText();
});

$scope.$watch('filterCity', function (value) {

    setFilterText();
});

function setFilterText()
{
    $scope.filterOptions.filterText = 'Name: ' + $scope.filterName + ';City:' + $scope.filterCity;
}

Кстати, я хотел использовать функцию компиляции, но, похоже, это не сработало. У меня было следующее, но это не сработало.

filterOptions.filterText = $compile('Name:{{filterName}};Category:{{filterCategory}}')(scope);

Другие вопросы по тегам