Jus*_*cha 132 javascript angularjs angularjs-ng-repeat
我想使用filter
in angular并想要过滤多个值,如果它有任何一个值,那么它应该显示.
我有这样的结构:
一个movie
具有属性的对象,genres
我想过滤Action
和Comedy
.
我知道我可以做filter:({genres: 'Action'} || {genres: 'Comedy'})
,但如果我想动态过滤该怎么办.例如filter: variableX
如何设置variableX
的$scope
,当我有我有过滤类型的数组?
我可以把它构造成一个字符串,然后做一个eval()
但我不想使用eval()...
Xes*_*ued 87
我只想创建一个自定义过滤器.他们并不那么难.
angular.module('myFilters', []).
filter('bygenre', function() {
return function(movies,genres) {
var out = [];
// Filter logic here, adding matches to the out var.
return out;
}
});
Run Code Online (Sandbox Code Playgroud)
<h1>Movies</h1>
<div ng-init="movies = [
{title:'Man on the Moon', genre:'action'},
{title:'Meet the Robinsons', genre:'family'},
{title:'Sphere', genre:'action'}
];" />
<input type="checkbox" ng-model="genrefilters.action" />Action
<br />
<input type="checkbox" ng-model="genrefilters.family" />Family
<br />{{genrefilters.action}}::{{genrefilters.family}}
<ul>
<li ng-repeat="movie in movies | bygenre:genrefilters">{{movie.title}}: {{movie.genre}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
这里编辑链接:创建角度过滤器
更新:这是一个小提琴,有一个我的建议的精确演示.
jla*_*eau 79
您可以使用控制器功能进行过滤.
function MoviesCtrl($scope) {
$scope.movies = [{name:'Shrek', genre:'Comedy'},
{name:'Die Hard', genre:'Action'},
{name:'The Godfather', genre:'Drama'}];
$scope.selectedGenres = ['Action','Drama'];
$scope.filterByGenres = function(movie) {
return ($scope.selectedGenres.indexOf(movie.genre) !== -1);
};
}
Run Code Online (Sandbox Code Playgroud)
HTML:
<div ng-controller="MoviesCtrl">
<ul>
<li ng-repeat="movie in movies | filter:filterByGenres">
{{ movie.name }} {{ movie.genre }}
</li>
</ul>
</div>
Run Code Online (Sandbox Code Playgroud)
chr*_*arx 23
在这里创建自定义过滤器可能有点过分,如果您有多个值,则可以传入自定义比较器:
$scope.selectedGenres = "Action, Drama";
$scope.containsComparator = function(expected, actual){
return actual.indexOf(expected) > -1;
};
Run Code Online (Sandbox Code Playgroud)
然后在过滤器中:
filter:{name:selectedGenres}:containsComparator
Run Code Online (Sandbox Code Playgroud)
小智 17
这是自定义过滤器的实现,它将使用值数组过滤数据.它将支持具有数组和单个键值的多个键对象.正如inangularJS API中所提到的,AngularJS过滤器Doc支持多个具有单值的键过滤器,但是下面的自定义过滤器将支持与angularJS相同的功能,并且还支持值数组以及数组和单个键组合的组合.请在下面找到代码片段,
myApp.filter('filterMultiple',['$filter',function ($filter) {
return function (items, keyObj) {
var filterObj = {
data:items,
filteredData:[],
applyFilter : function(obj,key){
var fData = [];
if (this.filteredData.length == 0)
this.filteredData = this.data;
if (obj){
var fObj = {};
if (!angular.isArray(obj)){
fObj[key] = obj;
fData = fData.concat($filter('filter')(this.filteredData,fObj));
} else if (angular.isArray(obj)){
if (obj.length > 0){
for (var i=0;i<obj.length;i++){
if (angular.isDefined(obj[i])){
fObj[key] = obj[i];
fData = fData.concat($filter('filter')(this.filteredData,fObj));
}
}
}
}
if (fData.length > 0){
this.filteredData = fData;
}
}
}
};
if (keyObj){
angular.forEach(keyObj,function(obj,key){
filterObj.applyFilter(obj,key);
});
}
return filterObj.filteredData;
}
}]);
Run Code Online (Sandbox Code Playgroud)
用法:
arrayOfObjectswithKeys | filterMultiple:{key1:['value1','value2','value3',...etc],key2:'value4',key3:[value5,value6,...etc]}
Run Code Online (Sandbox Code Playgroud)
这是一个小提琴示例,实现了上面的"filterMutiple"自定义过滤器. :::小提琴示例:::
小智 13
如果你想过滤对象阵列,你可以给
filter:({genres: 'Action', key :value }.
个别属性将通过为该属性指定的特定过滤器进行过滤.
但是如果您想要通过单个属性过滤并对所有属性进行全局过滤,那么您可以执行类似这样的操作.
<tr ng-repeat="supp in $data | filter : filterObject | filter : search">
Run Code Online (Sandbox Code Playgroud)
〜阿图尔
我已经花了一些时间在它上面并且感谢@chrismarx,我看到angular的默认filterFilter
允许你传递自己的比较器.这是多个值的编辑比较器:
function hasCustomToString(obj) {
return angular.isFunction(obj.toString) && obj.toString !== Object.prototype.toString;
}
var comparator = function (actual, expected) {
if (angular.isUndefined(actual)) {
// No substring matching against `undefined`
return false;
}
if ((actual === null) || (expected === null)) {
// No substring matching against `null`; only match against `null`
return actual === expected;
}
// I edited this to check if not array
if ((angular.isObject(expected) && !angular.isArray(expected)) || (angular.isObject(actual) && !hasCustomToString(actual))) {
// Should not compare primitives against objects, unless they have custom `toString` method
return false;
}
// This is where magic happens
actual = angular.lowercase('' + actual);
if (angular.isArray(expected)) {
var match = false;
expected.forEach(function (e) {
e = angular.lowercase('' + e);
if (actual.indexOf(e) !== -1) {
match = true;
}
});
return match;
} else {
expected = angular.lowercase('' + expected);
return actual.indexOf(expected) !== -1;
}
};
Run Code Online (Sandbox Code Playgroud)
如果我们想为DRY制作自定义过滤器:
angular.module('myApp')
.filter('filterWithOr', function ($filter) {
var comparator = function (actual, expected) {
if (angular.isUndefined(actual)) {
// No substring matching against `undefined`
return false;
}
if ((actual === null) || (expected === null)) {
// No substring matching against `null`; only match against `null`
return actual === expected;
}
if ((angular.isObject(expected) && !angular.isArray(expected)) || (angular.isObject(actual) && !hasCustomToString(actual))) {
// Should not compare primitives against objects, unless they have custom `toString` method
return false;
}
console.log('ACTUAL EXPECTED')
console.log(actual)
console.log(expected)
actual = angular.lowercase('' + actual);
if (angular.isArray(expected)) {
var match = false;
expected.forEach(function (e) {
console.log('forEach')
console.log(e)
e = angular.lowercase('' + e);
if (actual.indexOf(e) !== -1) {
match = true;
}
});
return match;
} else {
expected = angular.lowercase('' + expected);
return actual.indexOf(expected) !== -1;
}
};
return function (array, expression) {
return $filter('filter')(array, expression, comparator);
};
});
Run Code Online (Sandbox Code Playgroud)
然后我们可以在任何我们想要的地方使用它:
$scope.list=[
{name:'Jack Bauer'},
{name:'Chuck Norris'},
{name:'Superman'},
{name:'Batman'},
{name:'Spiderman'},
{name:'Hulk'}
];
<ul>
<li ng-repeat="item in list | filterWithOr:{name:['Jack','Chuck']}">
{{item.name}}
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
最后,这是一个傻瓜.
注意:预期数组应该只包含String,Number等简单对象.
您可以使用searchField过滤angular.filter
JS:
$scope.users = [
{ first_name: 'Sharon', last_name: 'Melendez' },
{ first_name: 'Edmundo', last_name: 'Hepler' },
{ first_name: 'Marsha', last_name: 'Letourneau' }
];
Run Code Online (Sandbox Code Playgroud)
HTML:
<input ng-model="search" placeholder="search by full name"/>
<th ng-repeat="user in users | searchField: 'first_name': 'last_name' | filter: search">
{{ user.first_name }} {{ user.last_name }}
</th>
<!-- so now you can search by full name -->
Run Code Online (Sandbox Code Playgroud)
ngIf
如果情况允许,您也可以使用:
<div ng-repeat="p in [
{ name: 'Justin' },
{ name: 'Jimi' },
{ name: 'Bob' }
]" ng-if="['Jimi', 'Bob'].indexOf(e.name) > -1">
{{ p.name }} is cool
</div>
Run Code Online (Sandbox Code Playgroud)
我发现最快的解决办法是使用filterBy
过滤器从角滤波器,例如:
<input type="text" placeholder="Search by name or genre" ng-model="ctrl.search"/>
<ul>
<li ng-repeat="movie in ctrl.movies | filterBy: ['name', 'genre']: ctrl.search">
{{movie.name}} ({{movie.genre}}) - {{movie.rating}}
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
好处是角度过滤器是一个相当受欢迎的库(GitHub上约2.6k星),它仍然在积极开发和维护,所以将它作为依赖项添加到项目中应该没问题.
归档时间: |
|
查看次数: |
250566 次 |
最近记录: |