【问题标题】:Recursive search and filtering in a menu菜单中的递归搜索和过滤
【发布时间】:2019-10-07 14:12:18
【问题描述】:

我正在开发一个 Angular 应用程序。 我的问题是这样的: 我在侧面有一个导航菜单,可以在菜单内进行搜索。 这是菜单的 JSON

menuItems: [
{
    name: "Dashboard",
    iconPath: "Dash@board.png",
    routingPath: "",
    children: [
        {
            name: "Version 1",
            iconPath: "",
            routingPath: "",
            children: [
                {
                    name: "Version 1.1 abc",
                    iconPath: "",
                    routingPath: "",
                    children: [
                        {
                            name: "Version 1.1.1 ccc",
                            iconPath: "",
                            routingPath: "",
                            children: [
                                {
                                    name: "Version 1.1.1.1 hello",
                                    iconPath: "",
                                    routingPath: "",
                                    children: []
                                },
                                {
                                    name: "Version 1.1.2.1",
                                    iconPath: "",
                                    routingPath: "",
                                    children: []
                                },
                                {
                                    name: "Version 1.1.3.1 sdfsdf",
                                    iconPath: "",
                                    routingPath: "",
                                    children: []
                                }
                            ]
                        },
                        {
                            name: "Version 1.1.2",
                            iconPath: "",
                            routingPath: "",
                            children: []
                        },
                        {
                            name: "Version 1.1.3",
                            iconPath: "",
                            routingPath: "",
                            children: []
                        }
                    ]
                },
                {
                    name: "Version 1.2",
                    iconPath: "",
                    routingPath: "",
                    children: []
                }
            ]
        },
        {
            name: "Version 2",
            iconPath: "",
            routingPath: "",
            children: []
        },
        {
            name: "Version 3",
            iconPath: "",
            routingPath: "",
            children: [
                {
                    name: "Version 3.1",
                    iconPath: "",
                    routingPath: "",
                    children: []
                },
                {
                    name: "Version 3.2",
                    iconPath: "",
                    routingPath: "",
                    children: []
                },
                {
                    name: "Version 3.3",
                    iconPath: "",
                    routingPath: "",
                    children: []
                }
            ]
        }
    ]
},
{
    name: "Pages",
    iconPath: "Pa@ges.png",
    routingPath: "",
    children: [
        {
            name: "ZZZ Page 1",
            iconPath: "",
            routingPath: "",
            children: []
        }
    ]
},]

这是一个菜单示例。 我想要实现的是: 如果有人搜索你好,我需要显示这个(我只显示名称,但我需要对象内的所有数据):

但它不起作用。 我试过这段代码:

private performFiltering() {
    const searchValue: string = this.searchBarInput.nativeElement.value.toLowerCase();

    if (searchValue.length > 0) {
        this.filteredMenu.menuItems = this.fullMenu.menuItems.filter((item) => {
            return this.recursiveSearchInMenu(item, searchValue);
        });
}}

private recursiveSearchInMenu(menu: MenuItemModel, searchValue) {
    let found = menu.children.find((item) => item.name.toLowerCase().includes(searchValue));
    if (!found) {
        let i = 0;
        while (!found && i < menu.children.length) {
            if (menu.children[i].children && menu.children[i].children.length) {
                found = this.recursiveSearchInMenu(menu.children[i], searchValue);
            }
            i++;
        }
    }
    return found;
}

这是我的结果:

任何想法如何做到这一点?

【问题讨论】:

    标签: angular typescript recursion search filter


    【解决方案1】:

    我知道了……

    这是我目前的答案:

    private performFiltering(): boolean {
        const searchValue: string = this.searchBarInput.nativeElement.value.toLowerCase();
        const isFiltered = searchValue.length > 0;
    
        this.showSearchButton(isFiltered);
    
        if (isFiltered) {
            this.filteredMenu.menuItems = this.recursiveSearchInMenu(
                JSON.parse(JSON.stringify(this.fullMenu.menuItems)),
                searchValue
            );
        } else {
            this.filteredMenu.menuItems = this.fullMenu.menuItems;
        }
    
        return isFiltered;
    }
    
    private recursiveSearchInMenu(menuItems: MenuItemModel[], searchValue: string): MenuItemModel[] {
        const matchingMenuItems: MenuItemModel[] = [];
    
        menuItems.forEach((menuItem) => {
            if (menuItem.name.toLowerCase().includes(searchValue)) {
                matchingMenuItems.push(menuItem);
            } else {
                const matchingChildren = this.recursiveSearchInMenu(menuItem.children, searchValue);
    
                if (matchingChildren.length > 0) {
                    menuItem.children = matchingChildren;
                    matchingMenuItems.push(menuItem);
                }
            }
        });
    
        return matchingMenuItems;
    }
    

    如果您对如何改进它有任何建议,我很乐意听取您的意见。

    【讨论】:

      【解决方案2】:

      如果我正确理解了您的问题 - 您的示例代码将不起作用,因为 this.fullMenu.menuItems.filter 将仅过滤父对象(仪表板)而不过滤此对象的内容。 您可以创建像 recursiveSearchInMenu 这样的函数,它将使用过滤选项构建数组(再添加一个哈希变量,用于存储找到的子对象) 类似的东西。

      private recursiveSearchInMenu(menu: MenuItemModel, searchValue) {
          let result = [];
          let found = menu.children.find((item) => item.name.toLowerCase().includes(searchValue));
          if(found)
          {
              result.add(found);
          }else {
              let i = 0;
              while (!found && i < menu.children.length) {
                  if (menu.children[i].children && menu.children[i].children.length) {
                      found = this.recursiveSearchInMenu(menu.children[i], searchValue);  
                      if(found.Length > 0) {
                          result.add({name: menu.children[i].name,
                          iconPath: menu.children[i].iconPath,
                          routingPath : menu.children[i].routingPath,
                          children: found})
                      }
                  i++;
               }
              }
          }
          return result;
      }
      

      【讨论】:

      • 包含您建议的函数的代码将使您的答案更加有用。
      猜你喜欢
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 2016-02-07
      • 2014-07-29
      相关资源
      最近更新 更多