Рекурсивный поиск и фильтрация в меню - PullRequest
0 голосов
/ 21 мая 2019

У меня есть угловое приложение, над которым я работаю.Моя проблема заключается в следующем: у меня есть боковое меню навигации с возможностью поиска внутри меню.это 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: []
        }
    ]
},]

это пример для меню.я пытаюсь добиться этого: если кто-то ищет привет, мне нужно отобразить это (я отображаю только имя, но мне нужны все данные внутри объекта):

enter image description here

Но это не работает.Я пробовал этот код:

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

Это мой результат: enter image description here

есть идеи, как это сделать?

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Если я понял вашу проблему правильно - ваш код из примера не будет работать, потому что this.fullMenu.menuItems.filter будет фильтровать только родительский объект (Dashboard) без фильтрации содержимого этих объектов.Вы можете создать функцию наподобие 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;
}
0 голосов
/ 27 мая 2019

Я понял ...

это мой текущий ответ:

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

если у вас есть предложения по его улучшению, я бы хотел узнать ваше мнение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...