我尝试根据多个过滤器构建产品列表。我认为这应该是非常直接的,但它至少不适合我。
这是plunkr http://plnkr.co/edit/vufFfWyef3TwL6ofvniP?p=preview
复选框是从相应的模型动态生成的,例如sizes
,colours
,categories
。子类别检查表应该执行“或”操作。查询但应该执行的横截面' 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
分配正确值的方法。
现在作为最新尝试(在plunkr中)我正在尝试使用自定义过滤器。它也没有返回OR结果。
现在我将它用作productFilter:search.categories:'categories'
如果它已经返回OR结果然后我计划将其用作 -
`productFilter:search.categories:'categories' | productFilter:search.colours:'colours' | productFilter:search.sizes:'sizes'`
因为我在这里寻求帮助,所以最好有productFilter:search
。
我花了相当多的时间来找到这个所谓的简单问题的解决方案,但大多数例子都使用了非动态的问题。复选框或扁平物体。
可能是我在错误的方向思考,并且对于这样的场景有更优雅和简单的Angular方式。我希望能够针对类似解决方案的任何解决方案,其中嵌套对象可以使用自动动态生成的过滤器进行过滤。对于任何购物应用程序来说,这似乎是非常通用的用例,但到目前为止还没有运气。
答案 0 :(得分:1)
首先需要了解的是:从任何定义来看,这个问题都不简单。您希望根据数组中对象的属性找到匹配项,该数组是您提供的输入数组内对象的属性,更不用说[OR intra group] + [AND inter group]关系,搜索由.title
或.name
定义的属性,以及完全动态的条件选择。这是一个复杂的问题。
虽然这是购物车网站的常见场景,但我怀疑任何网络框架都会在其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
。count
函数中的helper
变量用于跟踪我们针对特定条件组检查的复选框的数量。如果我们没有通过,则表示整个条件组无效,我们只返回true
。filter
是一个很好的设计。这就是为什么使用count
比调用cleanObj()
更好的原因。在为团队中使用的其他开发人员设计通用组件时,这一点尤其重要:您希望尽可能减少意外因素。