繁体   English   中英

如何在AngularJS中使用动态多个复选框过滤嵌套对象数组。 或与和过滤

[英]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

复选框是根据相应的模型动态生成的,例如sizescolourscategories 子类别检查框应执行“ 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM