Я пытаюсь построить таблицу с помощью ngTable, но с другой настраиваемой фильтрацией, чем описано в примере с страницы ngTable.
Я хочу, чтобы фильтрация была на месте, но я не хочу, чтобы ngTable отображал селектора фильтров. Я хочу сделать их самостоятельно (над таблицей), а затем ссылаться на них в методе getData().
Пример, упомянутый ранее, не объясняет, как работает любое из этих механизмов. Я не знаю, что именно должно быть указано в свойстве "filter" в каждом элементе "td". Я понимаю базовый синтаксис функции фильтра AngularJS $, но я не понимаю, что делает ngTable с этим. Из одного примера, похоже, что я могу выполнять только проверку "равно", которая будет выбирать только строки, где соответствующее значение столбца равно значению фильтра. Это не совсем то, что мне нужно.
В моей таблице несколько столбцов. Два из них называются "ключ" и "неудачны", являясь строкой и булевыми соответственно. Когда я создаю эти поля фильтра над таблицей, мне нужен специальный ярлык для фильтра с ошибкой. Фильтрация для столбца "ключ" должна соответствовать значению фильтра с любой подстрокой значений "ключ" . Например, если у меня есть ключевые значения "abc", "abac" и "def", значение фильтра "a" приведет к тому, что первые две записи будут показаны и не будут отображаться "def".
Update:
В связи с этим мне хотелось бы выяснить, как это сделать:
Скажем, у меня есть выражение ngRepeat в моем элементе таблицы, как это, используя "стандартные" фильтры angularjs:
"item in $data | customfilter:param | anothercustomfilter:param"
Мы знаем, что это не совсем работает, поскольку эти фильтры применимы только к одному фрагменту страницы, полученному из метода getData(). То, что я действительно хотел бы сделать в моем методе getData(), - это просто получить доступ ко всей цепочке фильтров, включая выражения параметров, и просто передать в нее другой массив, являющийся полным списком исходных данных, а не только срез страницы.
В то же время мне нужно было бы "выключить", чтобы угловое действие фильтрации выполнялось само по себе, выполняя эту цепочку фильтров в своей нормальной обработке.
Это звучит сложно, но я считаю, что текущий API требует большой связи между html и javascript. Было бы неплохо, если бы html мог указать желаемую фильтрацию, и javascript просто использовал бы всю целую цепочку фильтров, но использовал ее во всем списке данных, а не только для фрагмента страницы.
Update:
Вот соответствующий отрывок из моего HTML:
<label for="keysFilter">Filter Keys:</label>
<input id="keysFilter" type="text" ng-model="keysFilter"/>
<label for="showOnlyFailed">Show only queries that failed?</label>
<input id="showOnlyFailed" type="checkbox" ng-model="showOnlyFailed"/>
<table ng-table="tableParams" table-pagination="custom/pages" class="table">
<tr ng-repeat="queryInfo in $data"> <!-- | filterFailed:showOnlyFailed | filterMatchingKeys:keysFilter -->
Здесь мой код tableParams:
$scope.tableParams = new ngTableParams({
page: 1,
count: 10,
sorting: {
lastRun: 'desc'
}
},
{
debugMode: true,
total: $scope.completedQueries.length,
getData: function($defer, params) {
var orderedData = params.sorting() ?
$filter('orderBy')($scope.completedQueries, params.orderBy()) :
data;
orderedData = $filter('filterFailed')(orderedData, $scope.showOnlyFailed);
orderedData = $filter('filterMatchingKeys')(orderedData, $scope.keysFilter);
params.total(orderedData.length);
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(),
params.page() * params.count()));
}
});
Обратите внимание, что я использовал этот ngTable, не используя список "$ data", и просто повторяю его через список "completedQueries". Когда это сработает, список сразу изменится, когда я щелкнул флажок "Показывать только запросы, которые не удалось" или ввел текст в поле ввода "keysFilter".
Однако теперь, когда я использую список "$ data", ничего не происходит, когда я меняю одно из этих полей. Фактически, я даже добавил $watch-es для обоих этих полей, и ни один из них не стрелял. Однако, когда я вношу изменения в любое из этих полей, я знаю, что данные таблицы переоцениваются, потому что два из столбцов имеют данные, которые, как ожидается, будут миллис-значением, и у меня есть настраиваемый фильтр для этих столбцов, которые переводят значение в "временное" английское выражение, например "30 секунд назад" или "2 минуты назад", и каждый раз, когда я меняю одно из этих полей ввода, я вижу, что эти выражения в таблице меняются, но он все еще не выполняет правильная фильтрация.
Если это имеет значение, вот $watch-es, которые я добавил в свою область. Они никогда не срабатывают:
$scope.$watch("showOnlyFailed", function() {
$scope.tableParams.reload();
});
$scope.$watch("keysFilter", function() {
$scope.tableParams.reload();
});
Обратите внимание, что когда я прокомментировал это, я вижу следующую ошибку после того, как ударил мой метод getData():
Error: settings.$scope is null @http://localhost:8000/js/diag/libs/ng-table.src.js:411 qFactory/defer/deferred.promise.then/[email protected]://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:11046 qFactory/ref/<.then/<@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:11132 [email protected]://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:12075 [email protected]://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:11903 [email protected]://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:12179 bootstrap/doBootstrap/<@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:1341 [email protected]://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:3762 bootstrap/[email protected]://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:1340 [email protected]://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:1353 [email protected]://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:1301 @http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:21048 n.Callbacks/[email protected]://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2 n.Callbacks/[email protected]://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2 [email protected]://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2 [email protected]://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2 http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js Line 9509
Это соответствующий блок кода:
$defer.promise.then(function (data) {
settings.$loading = false;
log('ngTable: current scope', settings.$scope);
if (settings.groupBy) {
self.data = settings.$scope.$groups = data;
} else {
self.data = settings.$scope.$data = data; // line 411
}
settings.$scope.pages = self.generatePagesArray(self.page(), self.total(), self.count());
});
Update:
Вот мой plunkr, который демонстрирует, что изменение полей внешнего фильтра не работает. У меня также есть два $watch-es, прокомментированных, чтобы попытаться исправить это. Когда я прокомментирую это, я получаю сообщение об ошибке в ng-таблице, жалуясь на нулевую область.
Update:
Я попытался добавить параметры newvalue, oldvalue к моим $watch-es (я обновил plunkr). Теперь изменения в полях вызывают обновление таблицы. К сожалению, я все еще получаю эту трассировку стека в строке 411 ng-таблицы.