AngularJS 在树结构上按 属性 过滤对象

AngularJS filter object by property on tree structure

我发布这个是因为我从来没有找到过滤嵌套对象(树结构)的精确答案。

假设我们有一个 JSON 树结构,如下所示:

$scope.tree = [{
    id: 1,
    parent_id: 0,
    name: 'Root Item',
    items: [
              {
               id: 2, 
               parent_id: 1, 
               name: '1st Child of 1'
              },
              {
               id: 3, 
               parent_id: 1, 
               name: '2nd Child of 1'
              },
              {
               id: 4, 
               parent_id: 1, 
               name: '3rd Child of 1',
               items:[
                   {
                    id:5, 
                    parent_id: 4, 
                    name:'1st Child of 5'
                    },
                   {
                    id:6, 
                    parent_id: 4, 
                    name:'2nd Child of 5'
                    }
               ]}
           ]
    }]

我们如何使用过滤器遍历树以获得 id 为 6 的对象?

如果我们使用以下过滤器为例:

<div data-ng-init="selectedItem = (tree | filter:{id:6})">
  <h1>The name of item with id:6 is selectedItem.name</h1>
</div>

它只会遍历第一层,其中只会找到id:1。 因此,为了获得嵌套级别的对象,我们必须使用像这样的递归过滤器:

angular.module("myApp",[])
   .filter("filterTree",function(){
       return function(items,id){
          var filtered = [];
          var recursiveFilter = function(items,id){
              angular.forEach(items,function(item){
                 if(item.id === id){
                    filtered.push(item);
                 }
                 if(angular.isArray(item.items) && item.items.length > 0){
                    recursiveFilter(item.items,id);              
                 }
              });
          };
          recursiveFilter(items,id);
          return filtered;
       }; 
    });
});

因此,要在标记中使用此过滤器,您可以这样称呼它:

<div data-ng-init="selectedItem = (tree | filterTree:6)">
  <h1>The name of item with id:6 is selectedItem.name</h1>
</div>

希望你觉得这有用,我花了一些时间来消化递归过滤器。

当然,此过滤器可以获取 1 项,因为它是 returns [0] 过滤数组的第一个对象。但是如果你想让它 return 超过 1 个结果,你只需要在 return 函数中删除那个 [0] 然后使用 ng-repeat迭代过滤后的结果。