Angular 过滤器:如何预过滤 angular 过滤器只考虑整个数据对象的一部分
Angular Filters: How to pre-filter so angular filters consider only a partial of the whole data object
我有一个大数据 table(它从 json api 获取数据)有多个列,我想实现多个过滤器来执行以下操作:
- select 应考虑哪个数据列的选项(包含 thead 选项的下拉列表)[my columnFilter]
然后
- 用于过滤特定数据部分的输入字段 [my searchFilter]
我可以使用 searchFilter,但我不确定如何连接 columnFilter 并使 searchFilter 仅适用于 selected 数据部分。
假设我只想看到包含世界 "blue" 的描述。
我如何绑定这两个过滤器并使它起作用?
这是我的一些代码:
Select data column:
<select ng-model="columnFilter" ng-options="heading for heading in headings">
</select>
</div>
<div class="col-sm-12">
Filter selection: <input type='text' ng-model="searchFilter" />
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>URL</th>
<th>Title</th>
<th>Traffic</th>
<th>Description</th>
<th>ID</th>
</tr>
</thead>
<tbody ng-repeat="url in urls | filter:searchFilter">
<tr>
<td>{{url.url}}</td>
<td>{{url.title}}</td>
<td>{{url.traffic}}</td>
<td>{{url.descr}}</td>
<td>{{url.id}}</td>
</tr>
</tbody>
</table>
和一个 link 给一个正在工作的 plunker:http://plnkr.co/edit/TddllGiey0RmCx18eVdd?p=preview
直接从创建自定义过滤器的 angular 页面查看此示例。 https://docs.angularjs.org/guide/filter
您可以在此处看到,您可以创建一个接受 2 个输入、实际对象和一个参数的过滤器。通过将列名称作为参数传递,您可以缩小对正确行的搜索范围。
我建议您像这样编写简单的自定义过滤器。
.filter('myfilter', function(){
return function(input, column, text){
if (!input || !column || !text) return input;
return input.filter(function(item){
var value = item[column.toLowerCase()];
if (!value)return false;
return value.indexOf(text)>-1;
});
};
});
您可以在 html 中使用此过滤器。
ng-repeat="url in urls | myfilter:columnFilter:searchFilter"
据我所知angular,有两种主要方法可以解决您的问题。
- 定义自定义过滤器
- 定义一个函数来过滤您的数据并使用 ng-show 或 ng-hide 调用它
I got a large data table
如果我理解得很好,你指定那个,因为性能是一个大问题。
有一篇很好的文章揭示了这两种解决方案之间的差异:http://www.bennadel.com/blog/2487-filter-vs-nghide-with-ngrepeat-in-angularjs.htm
由于性能对你来说可能真的很重要,我建议你采用第二种方法。
在您看来:
<tbody ng-repeat="url in urls" ng-show="filterUrl(url)">
在你的控制器中:
$scope.searchFilter = "";
$scope.columnFilter = $scope.headings[5];
$scope.filterUrl = function(url){
if(!$scope.searchFilter || $scope.searchFilter == "")
return url;
var searchFilter= $scope.searchFilter.toLowerCase();
var trafficString = url.traffic.toString();
var idString = url.traffic.toString();
switch($scope.columnFilter){
case $scope.headings[0]:
return url.title.toLowerCase().indexOf(searchFilter) != -1;
case $scope.headings[1]:
return url.url.toLowerCase().indexOf(searchFilter) != -1;
case $scope.headings[2]:
return trafficString.indexOf(searchFilter) != -1;
case $scope.headings[3]:
return url.descr.toLowerCase().indexOf(searchFilter) != -1;
case $scope.headings[4]:
return idString.indexOf(searchFilter) != -1;
case $scope.headings[5]:
return url.title.toLowerCase().indexOf(searchFilter) != -1 ||
url.url.toLowerCase().indexOf(searchFilter) != -1 ||
trafficString.indexOf(searchFilter) != -1 ||
url.descr.toLowerCase().indexOf(searchFilter) != -1 ||
idString.indexOf(searchFilter) != -1;
}
};
更新:
如果选择第一种方法:
在您看来:
<tbody ng-repeat="url in urls | filterByColumn: searchFilter :columnFilter">
过滤器:
app.filter('filterByColumn', function(){
return function(urls, text, columnFilter){
var processed = [];
if(!text || text == "")
return urls;
urls.forEach(function(url){
var searchFilter= text.toLowerCase();
var trafficString = url.traffic.toString();
var idString = url.traffic.toString();
switch(columnFilter){
case "Title":
if( url.title.toLowerCase().indexOf(searchFilter) != -1)
processed.push(url);
break;
case "Url":
if(url.url.toLowerCase().indexOf(searchFilter) != -1)
processed.push(url);
break;
case "Traffic":
if(trafficString.indexOf(searchFilter) != -1)
processed.push(url);
break;
case "Description":
if(url.descr.toLowerCase().indexOf(searchFilter) != -1)
processed.push(url);
break;
case "Id":
if( idString.indexOf(searchFilter) != -1)
processed.push(url);
break;
case "All":
if( url.title.toLowerCase().indexOf(searchFilter) != -1 ||
url.url.toLowerCase().indexOf(searchFilter) != -1 ||
trafficString.indexOf(searchFilter) != -1 ||
url.descr.toLowerCase().indexOf(searchFilter) != -1 ||
idString.indexOf(searchFilter) != -1)
processed.push(url);
break;
}
});
return processed;
};
});
这是一个 plunkr:http://plnkr.co/edit/xCwI2AURFpvb6xHgYHxS?p=preview
我有一个大数据 table(它从 json api 获取数据)有多个列,我想实现多个过滤器来执行以下操作:
- select 应考虑哪个数据列的选项(包含 thead 选项的下拉列表)[my columnFilter] 然后
- 用于过滤特定数据部分的输入字段 [my searchFilter]
我可以使用 searchFilter,但我不确定如何连接 columnFilter 并使 searchFilter 仅适用于 selected 数据部分。
假设我只想看到包含世界 "blue" 的描述。
我如何绑定这两个过滤器并使它起作用?
这是我的一些代码:
Select data column:
<select ng-model="columnFilter" ng-options="heading for heading in headings">
</select>
</div>
<div class="col-sm-12">
Filter selection: <input type='text' ng-model="searchFilter" />
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>URL</th>
<th>Title</th>
<th>Traffic</th>
<th>Description</th>
<th>ID</th>
</tr>
</thead>
<tbody ng-repeat="url in urls | filter:searchFilter">
<tr>
<td>{{url.url}}</td>
<td>{{url.title}}</td>
<td>{{url.traffic}}</td>
<td>{{url.descr}}</td>
<td>{{url.id}}</td>
</tr>
</tbody>
</table>
和一个 link 给一个正在工作的 plunker:http://plnkr.co/edit/TddllGiey0RmCx18eVdd?p=preview
直接从创建自定义过滤器的 angular 页面查看此示例。 https://docs.angularjs.org/guide/filter
您可以在此处看到,您可以创建一个接受 2 个输入、实际对象和一个参数的过滤器。通过将列名称作为参数传递,您可以缩小对正确行的搜索范围。
我建议您像这样编写简单的自定义过滤器。
.filter('myfilter', function(){
return function(input, column, text){
if (!input || !column || !text) return input;
return input.filter(function(item){
var value = item[column.toLowerCase()];
if (!value)return false;
return value.indexOf(text)>-1;
});
};
});
您可以在 html 中使用此过滤器。
ng-repeat="url in urls | myfilter:columnFilter:searchFilter"
据我所知angular,有两种主要方法可以解决您的问题。
- 定义自定义过滤器
- 定义一个函数来过滤您的数据并使用 ng-show 或 ng-hide 调用它
I got a large data table
如果我理解得很好,你指定那个,因为性能是一个大问题。
有一篇很好的文章揭示了这两种解决方案之间的差异:http://www.bennadel.com/blog/2487-filter-vs-nghide-with-ngrepeat-in-angularjs.htm
由于性能对你来说可能真的很重要,我建议你采用第二种方法。
在您看来:
<tbody ng-repeat="url in urls" ng-show="filterUrl(url)">
在你的控制器中:
$scope.searchFilter = "";
$scope.columnFilter = $scope.headings[5];
$scope.filterUrl = function(url){
if(!$scope.searchFilter || $scope.searchFilter == "")
return url;
var searchFilter= $scope.searchFilter.toLowerCase();
var trafficString = url.traffic.toString();
var idString = url.traffic.toString();
switch($scope.columnFilter){
case $scope.headings[0]:
return url.title.toLowerCase().indexOf(searchFilter) != -1;
case $scope.headings[1]:
return url.url.toLowerCase().indexOf(searchFilter) != -1;
case $scope.headings[2]:
return trafficString.indexOf(searchFilter) != -1;
case $scope.headings[3]:
return url.descr.toLowerCase().indexOf(searchFilter) != -1;
case $scope.headings[4]:
return idString.indexOf(searchFilter) != -1;
case $scope.headings[5]:
return url.title.toLowerCase().indexOf(searchFilter) != -1 ||
url.url.toLowerCase().indexOf(searchFilter) != -1 ||
trafficString.indexOf(searchFilter) != -1 ||
url.descr.toLowerCase().indexOf(searchFilter) != -1 ||
idString.indexOf(searchFilter) != -1;
}
};
更新: 如果选择第一种方法:
在您看来:
<tbody ng-repeat="url in urls | filterByColumn: searchFilter :columnFilter">
过滤器:
app.filter('filterByColumn', function(){
return function(urls, text, columnFilter){
var processed = [];
if(!text || text == "")
return urls;
urls.forEach(function(url){
var searchFilter= text.toLowerCase();
var trafficString = url.traffic.toString();
var idString = url.traffic.toString();
switch(columnFilter){
case "Title":
if( url.title.toLowerCase().indexOf(searchFilter) != -1)
processed.push(url);
break;
case "Url":
if(url.url.toLowerCase().indexOf(searchFilter) != -1)
processed.push(url);
break;
case "Traffic":
if(trafficString.indexOf(searchFilter) != -1)
processed.push(url);
break;
case "Description":
if(url.descr.toLowerCase().indexOf(searchFilter) != -1)
processed.push(url);
break;
case "Id":
if( idString.indexOf(searchFilter) != -1)
processed.push(url);
break;
case "All":
if( url.title.toLowerCase().indexOf(searchFilter) != -1 ||
url.url.toLowerCase().indexOf(searchFilter) != -1 ||
trafficString.indexOf(searchFilter) != -1 ||
url.descr.toLowerCase().indexOf(searchFilter) != -1 ||
idString.indexOf(searchFilter) != -1)
processed.push(url);
break;
}
});
return processed;
};
});
这是一个 plunkr:http://plnkr.co/edit/xCwI2AURFpvb6xHgYHxS?p=preview