Knockout点击绑定奇怪的行为

时间:2015-04-20 19:34:16

标签: javascript knockout.js

尝试获取基本的Knockout点击绑定设置,如下例所示:

<button id="btn-a" class="btn" data-bind="css: {'btn-primary':mode() == 'manual'}, click: $root.mode('manual')">Manual</button>
<button id="btn-b"  class="btn" data-bind="css: {'btn-primary':mode() == 'automatic'}, click: $root.mode('automatic')">Automatic</button>

<label>MODE: </label><span data-bind="text:mode()"></span>  

<script>

$(function () {

    var TestModel = function() {        
        var self = this;
        this.mode = ko.observable('manual');
    };

    var testModel = new TestModel();
    window.testModel = testModel;
    ko.applyBindings(testModel);

});

小提琴:http://jsfiddle.net/aq85wk65/     

然而,遇到两个问题:

  1. 绑定导致mode()值开始为 &#39;自动&#39;,即使我们明确地将其初始化为&#39;手册&#39;。
  2. 每当点击一个按钮时,javascript控制台会显示:
  3.   

    未捕获的TypeError:h.apply不是函数

3 个答案:

答案 0 :(得分:20)

您需要将您的点击处理程序包装在函数中:

http://jsfiddle.net/aq85wk65/1/

<button id="btn-a" class="btn" data-bind="css: {'btn-primary':mode() == 'manual'}, click: function(){$root.mode('manual')}">Manual</button>

请参阅http://knockoutjs.com/documentation/click-binding.html

答案 1 :(得分:6)

问题是你的click处理程序调用函数而不是使用它的引用。

这就是为什么你最后modeauto,因为click: $root.mode('automatic')正在设置可观察的值。

请改为尝试:

click: $root.mode.bind($root, 'manual')

答案 2 :(得分:3)

.bind答案或function() {}答案都有效;但通常我更愿意尽可能避免在我的视图中定义函数,而是将该逻辑移到ViewModel。

所以另一种选择,在这种情况下我可能会选择的是定义viewModel.setToManual()函数和viewModel.setToAutomatic()函数。

然后绑定处理程序就是

click: setToAutomatic

不仅视图中更干净,而且只要保留setToAutomatic(可能是类似的isAutomatic)的行为,它也可以保护视图免受ViewModel结构的更改