[英]How to filter nested object array with dynamic multiple check boxes in AngularJS. OR with and Filter
我试图建立基于多个过滤器的产品列表。 我认为这应该很简单,但至少不适合我。
这是plunkr http://plnkr.co/edit/vufFfWyef3TwL6ofvniP?p=preview
复选框是根据相应的模型动态生成的,例如sizes
, colours
, categories
。 子类别检查框应执行“ OR”查询,但横截面应执行“ AND”查询。
基本上像
filter:{categories:selectedcategories1} || {categories:selectedcategories2} | filter:{categories:selectedsizes1} || {categories:selectedsizes2}
问题是动态生成这些过滤器。 我也尝试在控制器中使用过滤器-
var tempArr = [{'categories':'selectedvalue1'}, {'categories':'selectedvalue2'}];
var OrFilterObjects = tempArr.join('||');
$scope.products = $filter('filter')($scope.products, OrFilterObjects, true);
但是找不到为OrFilterObjects
分配正确值的OrFilterObjects
。
现在,作为最新尝试(在plunkr中),我尝试使用自定义过滤器。 它也不返回或结果。
现在,我将其用作productFilter:search.categories:'categories'
如果它会返回OR结果),那么我打算将其用作-
`productFilter:search.categories:'categories' | productFilter:search.colours:'colours' | productFilter:search.sizes:'sizes'`
因为我在这里寻求帮助,所以很高兴有productFilter:search
。
我花了很多时间来找到这个简单问题的解决方案,但是大多数示例都使用“非动态”复选框或平面对象。
可能是我想的方向错误,在这种情况下有一种更优雅,更简单的Angular方法。 我很乐意针对类似解决方案的任何解决方案,其中可以使用自动动态生成的过滤器来过滤嵌套对象。 在我看来,任何购物应用程序都具有非常通用的用例,但到现在为止还没有运气。
您需要了解的第一件事:从任何定义上讲,这个问题都不简单。 您想基于数组中对象的属性找到匹配项,该属性是您要提供的输入数组中对象的属性,更不用说[OR组内] + [AND组间]关系,搜索属性由.title
或.name
定义,并且条件选择是完全动态的。 这是一个复杂的问题。
尽管这是购物车网站的常见情况,但我怀疑任何Web框架都将在其API中内置这种功能。 不幸的是,但我认为我们不能避免自己编写逻辑。
无论如何,由于最终您只想声明productFilter:search
,所以它是:
app.filter('productFilter', function($filter) {
var helper = function(checklist, item, listName, search) {
var count = 0;
var result = false;
angular.forEach(checklist, function(checked, checkboxName) {
if (checked) {
count++;
var obj = {};
obj[search] = checkboxName;
result = result || ($filter('filter')(item[listName], obj, true).length > 0);
}
});
return (count === 0) || result;
};
return function(input, definition) {
var result = [];
if (angular.isArray(input) && angular.isObject(definition)) {
angular.forEach(input, function(item) {
var matched = null;
angular.forEach(definition, function(checklist, listName) {
var tmp;
if (listName !== 'colours') {
tmp = helper(checklist, item, listName, 'title');
} else{
tmp = helper(checklist, item, listName, 'name');
}
matched = (matched === null) ? tmp : matched && tmp;
});
if (matched) result.push(item);
});
}
return result;
};
});
一些注意事项:
ng-repeat="product in products | productFilter:search"
。 input
必须是数组, definition
必须是对象。 如果您需要更多,可以在那做。 *.name
是该规则的一个例外(我假设大多数条件都是由*.title
定义的)。 因此,我们在if/else
。 helper
函数中的count
变量用于跟踪特定标准组中经过了多少个选中的复选框。 如果不进行任何操作,则意味着整个条件组都处于非活动状态 ,而我们只返回true
。 filter
是一个很好的设计。 这就是为什么使用count
优于调用cleanObj()
。 在设计供团队中其他开发人员使用的通用组件时,这一点尤为重要:您希望尽可能减少意外的因素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.