【问题标题】:AngularJS Filter on nested propertiesAngularJS过滤嵌套属性
【发布时间】:2023-03-31 10:00:01
【问题描述】:

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

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;
    });
}
});

【问题讨论】:

    标签: angularjs filter


    【解决方案1】:

    如果有第二个变量将第一个变量的所有子变量展平,不是更容易吗?您可以定义一个递归函数来执行此操作,例如...

    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);
    }
    

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

    【讨论】:

    • 我对递归方法真的很糟糕,我尝试了一个但没有成功。过滤器是否不适用于页面上实际显示的 var ?因为我看不到如何第二个var如果没有实际用在屏幕上,我可以使用它。我在下面添加了一个新代码,因为我无法在评论部分编写整个代码
    【解决方案2】:

    我不知道如何将它集成到我的代码中。我无法更改基本变量,因为我需要在此结构中将其显示在屏幕上。我可以创建另一个展平数组,但必须在我显示的 var 上应用过滤器,不是吗?所以我不能使用扁平化的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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-30
      • 2017-02-21
      • 2014-06-21
      • 1970-01-01
      • 2016-02-27
      • 1970-01-01
      • 2013-09-01
      • 1970-01-01
      相关资源
      最近更新 更多