KnockoutJS:跟踪菜单点击

时间:2011-03-13 17:39:53

标签: knockout.js jquery-templates

我刚刚开始玩KnockoutJS,它很吸引人。我成功创建了一些模板来渲染界面的两个面板,里面有“ul”嵌套菜单。

以下是我的模板:

<script id="menuItemTemplate" type="text/html">
    <li class='${ Class }' >
        <a class='${ Class }' data-bind='click: function() { viewModel.menuClicked(Id); }'>${ Name }</a>
        <ul class='${ Class }' data-bind='template: { name: "menuItemTemplate", foreach: Items }'></ul>
    <li>
</script>
<script id="menuTemplate" type="text/html">
    <ul class='${ Class }' data-bind='template: { name: "menuItemTemplate", foreach: Items }'></ul>
</script>
<script id="consoleTemplate" type="text/html">
    <div class='${ Class }' data-bind='template: { name: "menuTemplate", data: Menu }'></div>
</script>
<h2>Application Administration</h2>
<div id="console" class="console" data-bind='template: { name: "consoleTemplate", foreach: Panels }'>
</div>

以下是我的视图模型的简化代码:

$(function () {
var viewModel = {
    "Panels": [
        {
        "Id" : 1,
        "Class": "main",
        "Menu": {
            "Id": 1,
            "Class": "file",
            "Name": "File",
            "Items": [{
                "Id": 1,
                "Class": "open",
                "Name": "Open",
                "Items": []
            }]
        }
    }]
};

    $.ajax({
        url: 'console.asmx/Initialize',
        type: "POST",
        cache: false,
        contentType: "application/json; charset=utf-8",
        data: "{}",
        dataType: "json",
        success: function (data) {
            viewModel = data.d;
            viewModel.menuActive = ko.observable(false);
            viewModel.currentMenu = ko.observable(0);
            viewModel.menuClicked = function (id) {
                viewModel.menuActive(true);
                viewModel.currentMenu(id);
            };
            ko.applyBindings(viewModel);
        }
    });
});

到目前为止,面板和菜单都很好,但我现在需要知道点击了哪个菜单,并根据点击的菜单显示子菜单以及其他UI元素。我附加到超链接的函数在我点击任何超链接时抛出异常:'Uncaught ReferenceError: viewModel is not defined'

我还尝试将子菜单的可见性绑定到viewModel的“currentMenu”属性,但这破坏了所有内容:

<script id="menuItemTemplate" type="text/html">
    <li class='${ Class }' data-bind='visible: viewModel.menuActive && viewModel.currentMenu == Id'>
        <a class='${ Class }' data-bind='click: function() { viewModel.menuClicked(Id); }'>${ Name }</a>
        <ul class='${ Class }' data-bind='template: { name: "menuItemTemplate", foreach: Items }'></ul>
    <li>
</script>

如何正确绑定点击事件处理程序以及基于点击菜单的可见性?

1 个答案:

答案 0 :(得分:4)

您的问题是您的变量viewModel是在jQuery ready函数中定义的,因此数据绑定中的函数无法看到它,因为它不在全局范围内。即使在var viewModel = {}之外进行$(function() { ... });也可以。

您定义点击功能的方式对我来说很好。但是,您的可见逻辑应使用viewModel.menuActive()viewModel.currentMenu()来访问表达式中的值。

希望这会有所帮助。如果你遇到困难,很乐意进一步提供帮助。