我正在尝试使用 ngTable 构建一个表,但自定义过滤与 ngTable page 中的示例中描述的不同。
我想要就地过滤,但我不希望 ngTable 呈现过滤器选择器。我想自己渲染它们(在表格上方),然后在我的“getData()”方法中引用它们。
前面提到的例子并没有解释这些机器是如何工作的。我不知道每个“td”元素的“filter”属性中需要指定什么。我了解 AngularJS $filter 函数的基本语法,但我不清楚 ngTable 对此做了什么。从一个示例中,看起来我只能进行“等于”检查,这只会选择关联列值等于过滤器值的行。这不是我所需要的。
我的表有几列。其中两个被称为“key”和“failed”,分别是字符串和布尔值。当我在表格上方呈现这些过滤器字段时,我需要一个“失败”过滤器的自定义标签。过滤“key”列应将过滤器值与“key”值的任何子字符串匹配。例如,如果我的键值为“abc”、“abac”和“def”,则过滤器值“a”将导致前两个条目显示,而不显示“def”条目。
更新:
与此相关,我希望我能弄清楚如何做这样的事情:
假设我的表格元素中有一个 ngRepeat 表达式,使用“标准”angularjs过滤器:
"item in $data | customfilter:param | anothercustomfilter:param"
我们知道这不太有效,因为这些过滤器仅适用于从“getData()”方法获得的一个页面切片。我真正希望能够在我的“getData()”方法中做的是简单地访问整个过滤器链,包括参数表达式,并简单地将不同的数组传递给它,作为整个原始数据列表,而不仅仅是页面切片。
同时,我需要能够通过在正常处理中执行该过滤器链来“关闭” angularjs 自身正在执行的过滤。
这听起来很困难,但我发现当前的 API 需要在 html 和 javascript 之间进行大量耦合。如果 html 可以指定所需的过滤,那就太好了,并且 javascript 将只使用整个过滤器链,但在整个数据列表上使用它,而不仅仅是页面切片。
更新:
这是我的 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/wrappedCallback@http://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 Scope.prototype.$eval@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:12075 Scope.prototype.$digest@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:11903 Scope.prototype.$apply@http://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 invoke@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:3762 bootstrap/doBootstrap@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:1340 bootstrap@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js:1353 angularInit@http://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/j@http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2 n.Callbacks/k.fireWith@http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2 .ready@http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2 K@http://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());
});
更新:
这是我的plunkr,它证明更改外部过滤器字段不起作用。我也有两个 $watch-es 被注释掉以试图纠正这个问题。当我在其中发表评论时,我在 ng-table 中收到一个错误,抱怨为空范围。
更新:
我尝试将“newvalue,oldvalue”参数添加到我的 $watch-es(我更新了 plunkr)。现在对字段的更改导致表更新。不幸的是,我仍然在 ng-table 的第 411 行得到那个堆栈跟踪。