使用knockout时,jquery click事件未触发

时间:2012-05-08 20:48:28

标签: jquery knockout.js

根据knockout click binding documentation's "Note 3",Knockout阻止点击事件执行默认功能。要覆盖此行为,我所要做的就是从处理函数返回true。所以,我有这个标记:

<div data-bind="visible:Pages().length == 0">
    <div class="alert alert-info">Click "Parse" button.</div>
    <button class="btn" id="btnParse" title="Parse Tabs">Parse</button>
</div>

现在,我想将点击事件附加到按钮上,如下所示:

$(function () {       
    $('#btnParse').on('click', function () { alert('clicked'); return true;});
});

请注意,我从函数返回true。这个偶数处理程序从不会触发。我怎样才能做到这一点?

4 个答案:

答案 0 :(得分:7)

您的点击处理程序永远不会被触发的原因是因为它从未应用于您的元素。所以当你在jquery中这样做时:

$('.some-class').on('some-event', someFunction);

然后,要将处理程序绑定到该事件,首先jQuery必须找到您的$('.some-class')选择器。在您的情况下,绑定事件时,很可能还没有通过knockout将#btnParse呈现给页面。或者,也可能,原始元素被渲染,销毁,然后渲染另一个元素。在第二种情况下,事件处理程序不会保留在按钮上。一种替代方法(我不建议)是将处理程序绑定在DOM中更高的位置,例如document级别,并将事件过滤为只有标识为#btnParse的事件:

$(document).on('click', '#btnParse', function () { console.log('hi'); });

我不建议这样做的原因是因为这是一个糟糕的淘汰赛练习,你应该使用click绑定,因为其他一些帖子建议。此外,您正在使用id属性,对于模板化动态内容而言,这通常不是一个好主意 - 只需使用类,除非您绝对需要一个唯一静态元素的id。

至于如何正确使用淘汰赛的点击绑定,一个棘手的问题是你需要了解淘汰赛的范围。例如,如果您在循环中绑定了一个单击,并且您希望主视图模型中的处理程序,则必须引用父作用域,因为循环会更改您的上下文:

<!-- ko foreach: someCollection -->
    <a data-bind="click: $parent.someFunction"></a>
<!-- /ko -->

此外,如果您需要更改处理程序执行的Javascript上下文(this),那么您需要绑定点击处理程序,如下所示:

<!-- ko foreach: someCollection -->
    <a data-bind="click: $parent.someFunction.bind($parent)"></a>
<!-- /ko -->

稍微玩一下这个东西然后问一个新问题,如果你仍然感到困惑。祝你好运!

答案 1 :(得分:1)

我认为问题与敲门修改你试图绑定事件的DOM有关。要解决此问题,请尝试将click函数指定给父<div>元素。分配单击处理程序时,使用带选择器的重载指定仅在单击包含的按钮时才处理单击。例如,像这样更改div:

<div id="btnContainer" data-bind="visible:Pages().length == 0">
    <div class="alert alert-info">Click "Parse" button.</div>
    <button class="btn" id="btnParse" title="Parse Tabs">Parse</button>
</div>

然后将脚本更改为:

$(function () {       
    $('#btnContainer').on('click', '#btnParse', function () { alert('clicked');});
});

请注意,如果此<div>包含在修改DOM的另一个逻辑块(模板,foreach循环等)中,您可能需要将#btnContainer标记设置为第一个<button>的祖先不是这种逻辑块的一部分。

答案 2 :(得分:0)

在我的情况下,我正在使用observableArray,需要一些jQuery魔法应用于该数组中的每个项目。我对自定义绑定有一些问题,不想从该数组中的每个项目中获取两个变量。因此,在我的包装中,我将一些黑暗的mnagic添加到一个不可观察的项目作为一个函数,以便当名称被cliked时,我正在处理的地图将移动到该位置。

HTML:

<ul data-bind="foreach: filteredItems">
    <li class="seat">
        <span class="name" data-bind="text:fullName, click: toggleEmp"></span>
    </li>
</ul>

CODE:

function viewModel() {
    var vm = this;
    vm.empData = function(data) {
        var emp = this;
        emp.office_x_loc = ko.observable(data.xLoc);
        emp.office_y_loc = ko.observable(data.yLoc);
        emp.toggleEmp = function () {
            jQuery('#skyLineMap').lhpMegaImgViewer( 'setPosition', emp.office_x_loc(),emp.office_y_loc(), 0.8, false );
    };//*/
}//*/

我希望这会有所帮助

答案 3 :(得分:-1)

您为click绑定引用的注释是指viewmodel中的方法,而不是您的自定义单击处理程序。

换句话说,如果data-bind="click: doSomething"元素中有<button>,则视图模型中的doSomething()方法应该返回true,如果您希望它执行自定义处理程序。