Многоколоночная фильтрация ngGrid

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

Допустим, у меня есть столбец со следующими заголовками: Id, Name, Description. Когда я выполняю поиск, я хочу вернуть все строки, в которых идентификатор ИЛИ имя ИЛИ описание содержат поисковый запрос.

    $scope.pagingOptions = {
        pageSizes: [20, 50, 100],
        pageSize: 20,
        totalServerItems: 0,
        currentPage: 1
    };

    $scope.gridOptions =
        {
            data: 'myData',
            columnDefs: [
                { field: 'id', displayName: 'Id' },
                { field: 'name', displayName: 'Name' },
                { field: 'description', displayName: 'Description' },
                { displayName: 'Actions', cellTemplate: '<input type="button" data-ng-click="doSomething(row.entity)" value="Do Something" />'}],
            enablePaging: true,
            showFooter: true,
            showFilter: true,
            pagingOptions: $scope.pagingOptions,
            filterOptions: {
                filterText: "",
                useExternalFilter: false
            }
        };

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

$scope.filterUpdated = function () {
    $scope.gridOptions.filterOptions.filterText = 'id:' + $scope.filterText + ';name:' + $scope.filterText + ';description:' + $scope.filterText;
};

Однако, похоже, это делает И для всех столбцов. Можно ли добиться того, чего я хочу, с помощью модуля ngGrid?

Заранее спасибо,

Крис


person Chris Haines    schedule 30.05.2013    source источник
comment
Я новичок в AngularJS, но просмотрел все видео от johnlindquist / eggheadio / www.egghead.io, и я думаю, это ngfilter видео ответит на ваш вопрос. Он начинает объяснять, как можно использовать другой поисковый фильтр около 3:00; начали с поиска по всем столбцам, а затем перешли к определенным столбцам.   -  person Pixic    schedule 14.06.2013
comment
Может быть, это обсуждение вам поможет. фильтр ng-grid для каждого столбца   -  person darwinbaisa    schedule 21.06.2013
comment
Да, вы можете реализовать фильтрацию по столбцам с помощью опции внутренней фильтрации в конфигурации сетки. Я скоро поставлю к нему плункер с ответом   -  person orif    schedule 30.05.2014


Ответы (1)


Да, можно использовать фильтр ИЛИ, но после поиска в исходном коде ng-grid я не вижу, как это можно сделать, используя их filterOptions.filterText. Это может делать только фильтрацию И.

Решением было бы использовать filterOptions.useExternalFilter:true

Я также не нашел примеров этого, но, немного поигравшись с этим, я понял, что фильтр фактически создается путем воссоздания массива gridOptions.data object |. Это единственный недостаток этого фильтра.

Код Plunker находится здесь

Итак, в основном ваш код будет выглядеть так: index.html:

<body ng-controller="MyCtrl">
  <strong>Filter Name:</strong> </string><input type="text" ng-model="filterName"/>
  </br>
  OR
  </br>
  <strong>Filter Age:</strong> </string><input type="text" ng-model="filterAge"/>
  </br>
  <button ng-click="activateFilter()">Run Filter</button>
  <br/>
  <br/>
  <div class="gridStyle" ng-grid="gridOptions"></div>
</body>

И в вашем controller.js:

app.controller('MyCtrl', function($scope) {

$scope.filterOptions = {
  filterText: '',
  useExternalFilter: true
};

$scope.activateFilter = function() {
  var name = $scope.filterName || null;
  var age = ($scope.filterAge) ? $scope.filterAge.toString() : null;
  if (!name && !age) name='';

  $scope.myData = angular.copy($scope.originalDataSet, []);
  $scope.myData = $scope.myData.filter( function(item) {
    return (item.name.indexOf(name)>-1 || item.age.toString().indexOf(age) > -1);
  });
 };

 $scope.originalDataSet = [{name: "Moroni", age: 50},
               {name: "Tiancum", age: 43},
               {name: "Jacob", age: 27},
               {name: "Nephi", age: 29},
               {name: "Enos", age: 34}];

 $scope.myData = angular.copy($scope.originalDataSet, []);

 $scope.gridOptions = {
  data: 'myData',
  filterOptions:  $scope.filterOptions
 };
});

Это просто базовая фильтрация (используйте регулярное выражение и / или конвертируйте в нижний регистр для лучшего соответствия). Также обратите внимание, что если и имя, и возраст пусты, я устанавливаю имя как '', и тогда каждый элемент будет возвращать значение true внутри фильтра (что приведет к возврату всего набора данных).

Этот вариант намного лучше подходит для динамического набора данных (чтение - серверная загрузка), но он работает так же хорошо, но реплицирует исходный набор данных и применяет к нему фильтры.

person Gilad Peleg    schedule 24.08.2013