【问题标题】:How to handle nested menu in knockout viewmodel如何处理淘汰视图模型中的嵌套菜单
【发布时间】:2015-04-02 16:04:06
【问题描述】:

我在我的项目中使用了 knockoutjs。我有一个场景,我必须在我的视图模型中创建一个嵌套菜单,我这样做是这样的:

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>

但是,我觉得这种创建嵌套菜单的方法不好,因为假设如果我想以编程方式继续任何菜单项,那么用他的方法是不可能的?

谁能建议我处理这种情况的好方法?

【问题讨论】:

  • 看起来您已经以编程方式选择了菜单项:$root.goToMenu($parent, $data); 您还可以考虑为每个菜单项添加一些唯一 ID(如果他们还没有)。这可能会简化搜索和选择菜单项。

标签: javascript jquery knockout.js


【解决方案1】:

确保每个菜单项都有一个唯一标识符。对于您提供name 的示例数据就足够了,但您可能需要将fullPath 属性添加到菜单项视图模型。

您的goToMenu 函数现在可以只接受一个参数: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">

请参阅this fiddle 以获取演示。

由此你也可以猜到,甚至可以直接设置chosenMenu

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

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

请参阅this fiddle 以获取演示。

【讨论】:

    【解决方案2】:

    我昨天遇到了类似的情况。你可以看看我的解决方案 Is there any knockout plugin for showing a nested context menu?。要点是我使用模板绑定能够构建任何深度的分层菜单。

    【讨论】:

      猜你喜欢
      • 2013-07-08
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 2015-08-17
      • 2014-04-30
      • 2013-02-19
      相关资源
      最近更新 更多