Как работать с вложенным меню в нокаут-модели

0

Я использую knockoutjs в своем проекте. У меня есть сценарий, когда мне нужно создать вложенное меню в моей модели viewmodel, что мне понравилось:

self.menu = [
    { 
         name: 'Services', 
         sub: [{ name: 'Service-A' }, { name: 'Service-B' }] 
    },
    // etc
];

self.chosenMenu = ko.observable();

self.goToMenu = function (main, sub) {

    var selectedMenu = {
        main: main,
        sub: sub
    };

    self.chosenMenu(selectedMenu);
};

Мой взгляд:

<ul class="nav navbar-nav menuitems col-md-8" data-bind="foreach: menu">
    <li class="dropdown">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown">
          <span data-bind="text: name"></span></a>
        <ul class="dropdown-menu" role="menu" data-bind="foreach: sub">
            <li>
                <a href="javascript:void(0);" data-bind="text: name, 
                   click: function() { $root.goToMenu($parent, $data); }">
                </a> 
            </li>
        </ul>
    </li>
</ul>

Тем не менее, я чувствую, что такой подход создания вложенного меню не является хорошим, потому что предположим, что если я хочу программно программировать, то с его подходом это невозможно?

Может ли кто-нибудь предложить мне хороший подход к решению такого рода сценариев?

  • 0
    Похоже, вы уже выбираете пункты меню программно: $root.goToMenu($parent, $data); Вы также можете добавить какой-то уникальный идентификатор к каждому пункту меню (если у него его еще нет). Это может упростить поиск и выбор пунктов меню.
Теги:
knockout.js

2 ответа

0

Вчера я столкнулся с подобным сценарием. Вы можете взглянуть на мое решение. Есть ли какой-либо плагин для нокаута для отображения вложенного контекстного меню? , Главное, что я использовал привязку шаблона, чтобы иметь возможность создавать иерархическое меню любой глубины.

0

Убедитесь, что каждый элемент меню имеет уникальный идентификатор. Для примера данных, которые вы дали name будет достаточно, но вам, возможно, придется добавить свойство fullPath к моделям просмотра элементов меню.

Функция goToMenu теперь может принимать только один параметр: uniqueMenuIdentifier и рекурсивно uniqueMenuIdentifier все пункты меню, чтобы найти правильный, например:

function findMenuItem(menuList, uniqueMenuIdentifier) {
    for (var i = 0; i < menuList.length; i++) {
        if (menuList[i].name === uniqueMenuIdentifier) {
            return menuList[i];
        }
        if (!!menuList[i].sub) {
            var subItem = findMenuItem(menuList[i].sub, uniqueMenuIdentifier);
            if (!!subItem) {
                return subItem;
            }
        }
    }
    return null;
}

self.goToMenu = function (menuItem) {
    var uniqueMenuIdentifier = menuItem.name;
    var item = findMenuItem(self.menu, uniqueMenuIdentifier);
    self.chosenMenu(item);
}

Это позволяет значительно упростить привязку в теге привязки:

<a href="javascript:void(0);" data-bind="text: name, click: $root.goToMenu">

Смотрите эту скрипту для демонстрации.

Из этого вы также можете догадаться, что даже можно установить chosenMenu напрямую:

// No longer needed:
//function findMenuItem(menuList, uniqueMenuIdentifier) { }

self.goToMenu = function (menuItem) {
    self.chosenMenu(menuItem);
}

Смотрите эту скрипту для демонстрации.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню