AngularJS ng-grid filter filterТекстовый формат

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

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

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


person JayInNyc    schedule 06.12.2013    source источник


Ответы (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>'

Например,

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

Здесь за отображаемым именем «Дата» (не используйте значение поля, вы должны использовать отображаемое имя) следует двоеточие «:», а затем неполная строка. В результате выбраны только три записи, связанные с 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 issue 777 . Исправление было объединено после проблемы ng-grid 848. Я могу определенно подтвердить, что я вижу низкую производительность, когда фильтр, примененный к большому набору данных, очищается. Я еще не тестировал исправление.

ОБНОВЛЕНИЕ

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


нг-сетка 3.0

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

person JayInNyc    schedule 06.12.2013
comment
Отличный ответ - я бы хотел, чтобы он был в вики ngGrid github. com/angular-ui/ng-grid/wiki/Sorting-and-filtering Он решил одну загадку. Моим пользователям нужно искать строки, включающие символы двоеточия ':', которые преобладают в наборе данных моей сетки. Путем изменения пользовательской строки поиска таким образом, чтобы ':' и ';' заменяются экранированными эквивалентами, например: filterOptions.filterText = srchTxt.replace(/:/g, "\\x3a").replace(/;/g, "\\x3b"); Мне удалось решить проблему. - person willw; 16.01.2014
comment
@JayInNyc Спасибо за ответ. У меня есть один вопрос; есть ли способ выполнить операцию «ИЛИ», а не «И» с несколькими столбцами? - person Chi Row; 19.04.2014
comment
@ChiRow Единственная ссылка, которая у меня есть, - это этот ответ на SO: > stackoverflow.com/questions/16846678/ . Говорят, что filterOptions.filterText нельзя использовать для фильтров ИЛИ. Есть много людей, которые просили об этом. Я рекомендую вам зайти на #ng-grid на freenode и сделать запрос. Было бы здорово добавить функцию. - person JayInNyc; 21.04.2014
comment
Большое спасибо. Одно замечание - для меня это сработало также с использованием имени поля вместо отображаемого имени. Не уверен, почему, возможно, ng-grid был улучшен. - person JustAMartin; 28.04.2015
comment
@Мартин Привет, Мартин. Какую версию ты используешь? ng-grid продолжает развиваться. Кроме того, действительно ли ваши имена полей совпадают с вашими отображаемыми именами? В остальном это меня немного удивляет, по крайней мере, для версии 2.0.8. С другой стороны, в наши дни меня мало чем можно удивить. - person JayInNyc; 28.04.2015
comment
@JayInNyc Мое определение столбца — {field:'name', displayName:'Firmas nosaukums'},{field:'registration_number', 'Reģistrācijas numurs'}, и когда я устанавливаю для filterText значение name:a;registration_number:11;, оно правильно фильтрует данные по обоим условиям. У меня нг-сетка-2.0.14. - person JustAMartin; 28.04.2015
comment
@Мартин -- хорошо, тогда отлично. Похоже на изменение кода. Спасибо за это дополнение. - person JayInNyc; 28.04.2015
comment
Я разветвил Plnkr, созданный другим пользователем, и связал его с ng-grid 2.0.11: plnkr.co/edit /dpTT0RTYpL8wXUav1OgY - person JustAMartin; 28.04.2015

Основываясь на ответе 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);

person H20rider    schedule 14.04.2014