AngularJS过滤嵌套属性

时间:2015-09-15 09:15:33

标签: angularjs filter

我想在嵌套对象上创建一个过滤器,如下所示:

Object 1 :
 property1
 property2
 property3
 children : Child 1 :
             propertyChild1
             propertyChild2
            Child 2 :

等等。一个对象可以有多个子对象。没有指定深度限制。问题是我只想搜索对象的某些属性,所以我使用了:

 ng-repeat="groupLevel1 in groupLevel2.children | filter: {lineDescription: searchKeyword}"

这是在所有级别上搜索,但如果父级不包含searchKeyword,则不会显示所有子级(可能包含搜索)。我希望显示所有父级别,以便显示包含搜索关键字的子级别,即使父级与搜索不匹配也是如此。

我尝试了一些复杂的脚本,但它不起作用:

appReportingHoliday.filter('globalFilter', function(){
return function(array, predicate){
    return array.filter(function(val){
        var formattedObj = parseFloatInternational(predicate);
        var re = new RegExp(formattedObj, 'i');
        var initialArray = [];
        initialArray.push(val);
        var childIsNeeded = false;
        var toReturnTemp;
        var parents = [];
        var toReturn = [];
        while(initialArray!=null){
            angular.forEach(initialArray, function (currentVal) {
                toReturnTemp = false;
                //We check if the val is concerned by the search
                toReturnTemp = re.test(currentVal.lineDescription) || re.test(currentVal.acquiredHolidays) || re.test(currentVal.tokenHolidays) || re.test(currentVal.availableHolidays)
                        || re.test(currentVal.dailyCost) || re.test(currentVal.valuation);

                if (toReturnTemp) {
                    //if it is, we need to add the result to the toReturn array and also the parents that we could have saved in the according array
                    toReturn.push(currentVal);
                    toReturn.push(parents);
                    parents = [];
                }
                else {
                    //else we save it in the parents array if a child is needed
                    if(currentVal.children!=null) {
                        parents.push(currentVal);
                    }
                }
                var index = initialArray.indexOf(currentVal);
                initialArray.splice(index, 1);
                if(currentVal.children!=null) {
                    angular.forEach(currentVal.children, function (currentChild) {
                        initialArray.push(currentChild);
                    });

                }
            });
            if(initialArray.length==0) initialArray = null;
        }
        return toReturn;
    });
}
});

显示如下:

 <tr class="groupReportingTreeDatatable" ng-repeat-start="groupLevel3 in myData | filter: {lineDescription: searchKeyword}" ng-init="$index &lt; 2 ? groupLevel3.hideRows = false : groupLevel3.hideRows = true;" ng-class-even="'dataTable_row1'" ng-class-odd="'dataTable_row2'" spinner-handler-directive="">
                        ...
<tr class="groupReportingTreeDatatable" ng-hide="groupLevel3.hideRows" ng-init="groupLevel2.hideRows = true"  ng-repeat-start="groupLevel2 in groupLevel3.children | filter: {lineDescription: searchKeyword}" ng-class-even="'dataTable_row1'" ng-class-odd="'dataTable_row2'">

                        ...


 <tr ng-hide="groupLevel2.hideRows || groupLevel3.hideRows" ng-repeat="groupLevel1 in groupLevel2.children | filter: {lineDescription: searchKeyword}" ng-class-even="'dataTable_row1'" ng-class-odd="'dataTable_row2'" ng-repeat-end="">

编辑: 我尝试过其他适用于某些搜索但不适用于所有搜索的内容:(

appReportingHoliday.filter('globalFilter', function() {
return function (array, predicate) {
    return array.filter(function (val) {
        var formattedObj = parseFloatInternational(predicate);
        var re = new RegExp(formattedObj, 'i');
        var found = re.test(val.lineDescription) || re.test(val.acquiredHolidays) || re.test(val.tokenHolidays) || re.test(val.availableHolidays)
                        || re.test(val.dailyCost) || re.test(val.valuation);
        var child = val.children;

        while(child!=null && found == false){
            angular.forEach(child, function (currentChild) {
                if(found == false) {
                    console.log(currentChild.lineDescription)
                    found = re.test(currentChild.lineDescription) || re.test(currentChild.acquiredHolidays) || re.test(currentChild.tokenHolidays) || re.test(currentChild.availableHolidays)
                            || re.test(currentChild.dailyCost) || re.test(currentChild.valuation);
                }
            });
            child = child.children;
        }

        return found;
    });
}
});

2 个答案:

答案 0 :(得分:0)

第二个变量是不是更容易让你压扁第一个变量的所有孩子?你可以定义一个递归函数,比如......

var mainObject = ... ;//that's your object
var flattened = new Array();

function flatten(main,flat) {
    var children = main.children;
    for (var i=0;i<children.length;i++) {
         flatten(children[i],flat); // recursive call, depth-first
         delete children[i].children; // those are already treated
         flat.push(children[i]); // add children
    }
    delete main.children;
    flat.push(main);
}

现在您可以直接过滤属性。

答案 1 :(得分:0)

我不知道如何在我的代码中集成它。我无法更改基本变量,因为我需要在此结构中将其显示在屏幕上。我可以创建另一个扁平数组,但过滤器必须应用于var I显示,不是吗?所以我不能使用flattened var。我不得不承认我有点迷失^^

我将深度固定为3以使其更容易,所以现在我有了这个:

appReportingHoliday.filter('globalFilter', function() {
return function (array, predicate) {
    return array.filter(function (val) {
        var formattedObj = parseFloatInternational(predicate);
        var re = new RegExp(formattedObj, 'i');
        var found = re.test(val.lineDescription) || re.test(val.acquiredHolidays) || re.test(val.tokenHolidays) || re.test(val.availableHolidays)
                        || re.test(val.dailyCost) || re.test(val.valuation);
        var child = val.children;

        if(child!=null && found == false){
            angular.forEach(child, function (currentChild) {
                if(found == false) {
                    found = re.test(currentChild.lineDescription) || re.test(currentChild.acquiredHolidays) || re.test(currentChild.tokenHolidays) || re.test(currentChild.availableHolidays)
                            || re.test(currentChild.dailyCost) || re.test(currentChild.valuation);
                }
                if(currentChild.children!=null && found == false){
                    angular.forEach(currentChild.children, function (currentGrandChild) {
                        if(found == false) {
                            found = re.test(currentGrandChild.lineDescription) || re.test(currentGrandChild.acquiredHolidays) || re.test(currentGrandChild.tokenHolidays) || re.test(currentGrandChild.availableHolidays)
                                    || re.test(currentGrandChild.dailyCost) || re.test(currentGrandChild.valuation);
                        }
                    });
                }

            });
            child = child.children;
        }
        return found;
    });
  }
});

唯一的问题是,如果搜索是在父母身上,我希望显示所有孩子,但现在只显示匹配的孩子:s我找不到孩子的父母,我只有从父母到孩子的联系而不是相反:s