AngularJS 通过 属性 递归过滤树结构

AngularJS filter tree structure recursively by property

我现在尝试了很多东西,但没有取得太大的成功。假设我有一个这样的列表:

[
    {
        "name": "Africa",
        "translation": "Afrika",
        "someNum": 87207,
        "countries": [
            {
                "name": "Algeria",
                "translation": "Algerien",
                "someNum": 58020,
                "countries": null
            },
            {
                "name": "Morocco",
                "translation": "Marokko",
                "someNum": 27314,
                "countries": null
            },
            {
                "name": "Libya",
                "translation": "Lybien",
                "someNum": 77788,
                "countries": null
            },
            {
                "name": "Somalia",
                "translation": "Somalia",
                "someNum": 17945,
                "countries": null
            },
            {
                "name": "Kenya",
                "translation": "Kenia",
                "someNum": 12505,
                "countries": null
            },
            {
                "name": "Mauritania",
                "translation": "Mauretanien",
                "someNum": 25787,
                "countries": null
            },
            {
                "name": "South Africa",
                "translation": "S\u00fcdafrika",
                "someNum": 39997,
                "countries": null
            }
        ]
    },
    {
        "name": "America",
        "translation": "Amerika",
        "someNum": 48450,
        "countries": [
            {
                "name": "North America",
                "translation": "Nordamerika",
                "someNum": 23397,
                "countries": [
                    {
                        "name": "Canada",
                        "translation": "Kanada",
                        "someNum": 58709,
                        "countries": null
                    },
                    {
                        "name": "USA",
                        "translation": "USA",
                        "someNum": 64725,
                        "countries": [
                            {
                                "name": "New York",
                                "translation": "New York",
                                "someNum": 50202,
                                "countries": null
                            },
                            {
                                "name": "California",
                                "translation": "Kalifornien",
                                "someNum": 92801,
                                "countries": [
                                    {
                                        "name": "Los Angeles",
                                        "translation": "Los Angeles",
                                        "someNum": 78283,
                                        "countries": null
                                    },
                                    {
                                        "name": "San Diego",
                                        "translation": "San Diego",
                                        "someNum": 30373,
                                        "countries": null
                                    },
                                    {
                                        "name": "Sacramento",
                                        "translation": "Sacramento",
                                        "someNum": 50721,
                                        "countries": null
                                    },
                                    {
                                        "name": "San Francisco",
                                        "translation": "San Francisco",
                                        "someNum": 65772,
                                        "countries": null
                                    },
                                    {
                                        "name": "Bakersville",
                                        "translation": "Bakersville",
                                        "someNum": 20390,
                                        "countries": null
                                    }
                                ]
                            },
                            {
                                "name": "Lousiana",
                                "translation": "Lousiana",
                                "someNum": 26245,
                                "countries": null
                            },
                            {
                                "name": "Texas",
                                "translation": "Texas",
                                "someNum": 57720,
                                "countries": null
                            },
                            {
                                "name": "Nevada",
                                "translation": "Nevada",
                                "someNum": 41399,
                                "countries": null
                            },
                            {
                                "name": "Montana",
                                "translation": "Montana",
                                "someNum": 97221,
                                "countries": null
                            },
                            {
                                "name": "Virginia",
                                "translation": "Virginia",
                                "someNum": 64101,
                                "countries": null
                            }
                        ]
                    }
                ]
            },
            {
                "name": "Middle America",
                "translation": "Mittelamerika",
                "someNum": 60813,
                "countries": [
                    {
                        "name": "Mexico",
                        "translation": "Mexiko",
                        "someNum": 97953,
                        "countries": null
                    },
                    {
                        "name": "Honduras",
                        "translation": "Honduras",
                        "someNum": 40591,
                        "countries": null
                    },
                    {
                        "name": "Guatemala",
                        "translation": "Guatemala",
                        "someNum": 41592,
                        "countries": null
                    }
                ]
            },
            {
                "name": "South America",
                "translation": "S\u00fcdamerika",
                "someNum": 61507,
                "countries": null
            }
        ]
    },
    {
        "name": "Asia",
        "translation": "Asien",
        "someNum": 38179,
        "countries": [
            {
                "name": "China",
                "translation": "China",
                "someNum": 47266
            },
            {
                "name": "India",
                "translation": "Indien",
                "someNum": 33424,
                "countries": null
            },
            {
                "name": "Malaysia",
                "translation": "Malaysia",
                "someNum": 38010,
                "countries": null
            },
            {
                "name": "Thailand",
                "translation": "Thailand",
                "someNum": 41356,
                "countries": null
            },
            {
                "name": "Vietnam",
                "translation": "Vietnam",
                "someNum": 79489,
                "countries": null
            },
            {
                "name": "Singapore",
                "translation": "Singapur",
                "someNum": 53176,
                "countries": null
            },
            {
                "name": "Indonesia",
                "translation": "Indonesien",
                "someNum": 89895,
                "countries": null
            },
            {
                "name": "Mongolia",
                "translation": "Mongolei",
                "someNum": 42783,
                "countries": null
            }
        ]
    },
    {
        "name": "Europe",
        "translation": "Europa",
        "someNum": 84723,
        "countries": [
            {
                "name": "North",
                "translation": "Nord",
                "someNum": 16833,
                "countries": [
                    {
                        "name": "Norway",
                        "translation": "Norwegen",
                        "someNum": 11817,
                        "countries": null
                    },
                    {
                        "name": "Sweden",
                        "translation": "Schweden",
                        "someNum": 38210,
                        "countries": null
                    },
                    {
                        "name": "Finland",
                        "translation": "Finnland",
                        "someNum": 10669,
                        "countries": null
                    }
                ]
            },
            {
                "name": "East",
                "translation": "Ost",
                "someNum": 28434,
                "countries": [
                    {
                        "name": "Romania",
                        "translation": "Rum\u00e4nien",
                        "someNum": 45122,
                        "countries": null
                    },
                    {
                        "name": "Bulgaria",
                        "translation": "Bulgarien",
                        "countries": null
                    },
                    {
                        "name": "Poland",
                        "translation": "Polen",
                        "someNum": 84183,
                        "countries": null
                    }
                ]
            },
            {
                "name": "South",
                "translation": "S\u00fcd",
                "someNum": 71856,
                "countries": [
                    {
                        "name": "Italy",
                        "translation": "Italien",
                        "someNum": 76406,
                        "countries": null
                    },
                    {
                        "name": "Greece",
                        "translation": "Griechenland",
                        "someNum": 18189,
                        "countries": null
                    },
                    {
                        "name": "Spain",
                        "translation": "Spanien",
                        "someNum": 36148,
                        "countries": null
                    }
                ]
            },
            {
                "name": "West",
                "translation": "West",
                "someNum": 33487,
                "countries": [
                    {
                        "name": "France",
                        "translation": "Frankreich",
                        "someNum": 72622,
                        "countries": null
                    },
                    {
                        "name": "England",
                        "translation": "England",
                        "someNum": 51927,
                        "countries": null
                    },
                    {
                        "name": "Portugal",
                        "translation": "Portugal",
                        "someNum": 25502,
                        "countries": null
                    }
                ]
            }
        ]
    },
    {
        "name": "Oceania",
        "translation": "Ozeanien",
        "someNum": 69844,
        "countries": [
            {
                "name": "Australia",
                "translation": "Australien",
                "someNum": 17211,
                "countries": null
            },
            {
                "name": "New Zealand",
                "translation": "Neuseeland",
                "someNum": 87401,
                "countries": null
            }
        ]
    },
    {
        "name": "Arctica",
        "translation": "Arktis",
        "someNum": 67183,
        "countries": null
    },
    {
        "name": "Antarctica",
        "translation": "Antarktis",
        "someNum": 92518,
        "countries": null
    }
]

我试图实现的是找到所有 parents and/or children,匹配我的搜索条件,同时保持整棵树完好无损。

假设我正在搜索 Australia 作为 属性 name 的值。预期结果将是:

- Oceania
-- Australia

但我得到的是

- Oceania
-- Australia
-- New Zealand

另一个示例:我正在搜索 Kalifornien 作为 属性 translation 的值。预期结果将是:

- America
-- North America
--- USA
---- California
----- Bakersville
----- San Diego
----- Sacramento
----- San Francisco
----- Los Angeles

但实际结果绝对不是你所期望的那样。

所以我遇到的主要问题是,原来的 Angular 过滤器没有正确处理 children。

我已经设置了一个 Plunker 来演示问题:https://plnkr.co/edit/3FavpC8XB3hTvT94fZli?p=preview

我还可以更改 JSON 数据的格式,如果这样更容易实现适当的过滤。

编辑:

我取得了部分成功:https://plnkr.co/edit/lDoUK3?p=preview

只剩下一个问题了。如果我搜索(例如)加利福尼亚,object 的 countries 属性 中名称为加利福尼亚的 object 会丢失。所以最后一项是加利福尼亚(到目前为止还不错),但我还需要 Bakersville、San Diego & co。在它下面。

如果您想在列表中获取所选元素的子项,您应该添加其父项(或某些父项的父项)必须在过滤后出现在列表中的项。为此,我建议您创建一个递归函数:

this.getSelectedElementList = function(list, element) {
  var result;
  for (var i in list) {
    if (list[i].name.toLowerCase().indexOf(element) > -1) {
      return list[i];
    } else {
      if (list[i].countries && list[i].countries.length) {
        result = this.getSelectedElementList(list[i].countries, element);
        if (typeof result !== 'undefined') {
          return result;
        }
      }
    }
  }
  return result;
};

并且您可以在 preFilter 函数中调用它两次。第一次获取父对象:

var parentList = _self.getSelectedElementList(_self.listItems, _self.filterQuery.toLowerCase());

第二个检查当前项目是否在该对象内:

if (typeof parentList !== 'undefined' && parentList.countries && parentList.countries.length && typeof _self.getSelectedElementList(parentList.countries, item.name.toLowerCase()) !== 'undefined') {
  path.push(item);
}

由于您目前仅按名称过滤,因此我的建议是这样的。我也更新了你的 Plunkr