我有$scope.users
用于显示表格,我需要应用具有多个选项的过滤器,
这是$scope.users
对象:
[
{
"login": "andres.un1@mail.com",
"merchant": {
"merchantId": 500095,
"status": "ENABLED",
"defaultAccountId": null,
"accounts": {
"500092": "ADMIN",
"500178": "CONSULT",
"500180": "ADMIN",
"500182": "ADMIN",
"500201": "ADMIN"
}
},
"name": "Carlos"
},
{
"login": "andres.un2@mail.com",
"merchant": {
"merchantId": 500095,
"status": "DISABLED",
"defaultAccountId": null,
"accounts": {
"500092": "CONSULT",
"500178": "MANAGER",
"500180": "ADMIN",
"500182": "ADMIN",
"500201": "ADMIN"
}
},
"name": "Carlos Andres"
},
{
"login": "cosme.fulanito@mail.com",
"merchant": {
"merchantId": 500095,
"status": "DISABLED",
"defaultAccountId": null,
"accounts": {
"500092": "CONSULT",
"500178": "MANAGER",
"500180": "ADMIN",
"500182": "ADMIN",
"500201": "ADMIN"
}
},
"name": "Cosme"
}
]
在过滤器中,我从$scope
传递其他对象来过滤数据,在这种情况下是$scope.searchParams
,我之前在指令中计算过。
$scope.searchParams
:
[
{'name':'Cosme'},
{'login':'andres.un1@mail.com'},
{'status':'ENABLED'},
{'status':'DISABLED'},
{'account':'267123'},
{'account':'543987'},
{'account':'544111'},
{'account':'543987'}
]
如您所见,name
和login
在过滤器中是唯一的,但status
和account
可以在过滤器中应用多个值。这是我的方法,但我觉得非常无效,也不完整,因为没有多重过滤功能:
var secUser = function () {
return function (input, list) {
var out = [];
var nameArr = [],
loginArr = [],
statusArr = [],
profileArr = [],
accountsArr = [];
angular.forEach(list, function(filter){
console.log(filter);
if(filter.hasOwnProperty('name')){
nameArr.push(filter.name);
}
if(filter.hasOwnProperty('login')){
loginArr.push(filter.login);
}
if(filter.hasOwnProperty('status')){
statusArr.push(filter.status);
}
if(filter.hasOwnProperty('account')){
accountsArr.push(filter.account);
}
if(filter.hasOwnProperty('profile')){
profileArr.push(filter.profile);
}
});
angular.forEach(input, function(user){
// no filters applied
if(nameArr.length < 1 && loginArr.length < 1 &&
statusArr.length < 1 && accountsArr.length < 1 &&
profileArr.length < 1){
out.push(user);
}
// filters to be applied
else{
if(nameArr.indexOf(user.name) > -1){
out.push(user);
}
if(loginArr.indexOf(user.login) > -1){
out.push(user);
}
if(statusArr.indexOf(user.merchant.status) > -1){
out.push(user);
}
}
});
return out;
};
};
//-- register filter
app.filter('secUser', secUser);
最后,我是如何使用fiter:<tbody ng-repeat="user in users | secUser:searchParams " class="table-striped">
¿考虑到将来可以有更多的过滤器字段,是否有更好的方法来实现此过滤器?另外我认为与观点非常相配。
答案 0 :(得分:1)
有多种方法可以做到这一点,但有一个要求是你需要使searchParams
结构更通用。例如,这里我使用的是一个对象,其中每个键都是目标对象的路径,相应的值是一个包含您想要匹配的所有值的数组:
$scope.searchParams = {
'name': ['Cosme'],
'login': ['andres.un1@mail.com'],
'merchant.status' : ['ENABLED','DISABLED'],
'merchant.accounts' : ['267123','543987 ','544111','543987'],
}
然后,您可以更新过滤器以处理通用数据。它不能完全通用,因为它取决于您的业务逻辑,例如accounts
上的500092
或值CONSULT
是否匹配。这是一个更新的过滤器函数,用于处理数据中的三种目标:
name
status
accounts
JsFiddle(稍微修改数据以进行测试)
var secUser = function () {
return function (users, filters) {
return users.filter(function(user){
var match = false;
angular.forEach(filters, function(filterValues, keyPath){
if (match) return; // if we already found a match, don't continue searching
// get the target based on the contents of the keypath
var target = keyPath.split('.').reduce(function(object, key) {
// get the next part of the path, if exists
return object && object[key];
}, user); // initial value is the user object
if (target !== undefined){ // if the target exists for this item
var values = []; // stores the values from the item to search against
if(typeof target === "object") {
values = Object.keys(target);
}
else if (target.isArray) {
values = target;
} else {
values = [target];
}
// check if any entry in values matches any entry of the filter values
match = values.some(function (v) {
return filterValues.indexOf(v) >= 0;
});
}
});
return match;
});
};
};