KnockoutJS:跟踪菜单点击 [英] KnockoutJS: Tracking menu clicks

查看:20
本文介绍了KnockoutJS:跟踪菜单点击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用 KnockoutJS,它很有趣.我成功创建了一些模板来渲染界面的两个面板,其中包含ul"嵌套菜单.

这是我的模板:

<script id="menuTemplate" type="text/html"><ul class='${ Class }' data-bind='template: { name: "menuItemTemplate", foreach: Items }'></ul><script id="consoleTemplate" type="text/html"><div class='${ Class }' data-bind='template: { name: "menuTemplate", data: Menu }'></div><h2>应用管理</h2><div id="console" class="console" data-bind='template: { name: "consoleTemplate", foreach: Panels }'>

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

$(function () {var viewModel = {面板":[{身份证":1,"类": "主要",菜单": {身份证":1,"类": "文件","名称": "文件",项目": [{身份证":1,"类": "开放","名称": "打开",项目": []}]}}]};$.ajax({网址:'console.asmx/初始化',类型:POST",缓存:假,contentType: "application/json; charset=utf-8",数据: "{}",数据类型:json",成功:功能(数据){视图模型 = 数据.d;viewModel.menuActive = ko.observable(false);viewModel.currentMenu = ko.observable(0);viewModel.menuClicked = 函数(id){viewModel.menuActive(true);viewModel.currentMenu(id);};ko.applyBindings(viewModel);}});});

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

我还尝试将子菜单的可见性绑定到 viewModel 的currentMenu"属性,但这破坏了一切:

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

解决方案

你的问题是你的变量 viewModel 是在 jQuery ready 函数中定义的,所以你的数据绑定中的函数看不到它,因为它不是在全球范围内.甚至,在 $(function() { ... }); 之外做一个 var viewModel = {} 也可以.

您定义点击函数的方式在我看来很好.您的可见逻辑应该使用 viewModel.menuActive()viewModel.currentMenu() 来访问表达式中的值.

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

I have just started playing with KnockoutJS and it it fascinating. I successfully created some templates to render two panels of an interface with "ul" nested menus inside.

Here are my templates:

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

And here is the simplified code for my view model:

$(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);
        }
    });
});

So far, the panels and the menus are rendered fine but I now need to know which menu was clicked and show the sub-menu as well as other UI elements based on the clicked menu. The function I attached to the hyperlinks is throwing an exception: 'Uncaught ReferenceError: viewModel is not defined' when I click on any of the hyperlinks.

I also tried to bind the visibility of sub-menus to the "currentMenu" property of the viewModel but that broke everything:

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

How can I properly bind the click event handler as well as the visibility based on the clicked menu?

解决方案

Your issue is that your variable viewModel is defined in the jQuery ready function, so the functions in your data-binds can't see it, since it is not at the global scope. Even, doing a var viewModel = {} outside the $(function() { ... }); would work.

The way that you defined your click function looks good to me. Your visible logic though should use viewModel.menuActive() and viewModel.currentMenu() to access the values as they are in an expression.

Hope this helps. Would be happy to help further, if you get stuck.

这篇关于KnockoutJS:跟踪菜单点击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆