最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Knockout click binding strange behavior - Stack Overflow

programmeradmin4浏览0评论

Trying to get basic Knockout click binding set up, as per the example below:

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

});

Fiddle: /

However, running into two issues:

  1. The binding causes the mode() value to start out as 'automatic', even though we explicitly initialize it to 'manual'.
  2. Whenever a button is clicked, the javascript console shows:

Uncaught TypeError: h.apply is not a function

Trying to get basic Knockout click binding set up, as per the example below:

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

});

Fiddle: http://jsfiddle.net/aq85wk65/

However, running into two issues:

  1. The binding causes the mode() value to start out as 'automatic', even though we explicitly initialize it to 'manual'.
  2. Whenever a button is clicked, the javascript console shows:

Uncaught TypeError: h.apply is not a function

Share Improve this question asked Apr 20, 2015 at 19:34 YarinYarin 184k155 gold badges410 silver badges523 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 20

You need to wrap your click handlers in function:

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>

see http://knockoutjs.com/documentation/click-binding.html

The problem is that your click handler is invoking the function instead of using its reference.

That's why you're ending up with mode being auto, because click: $root.mode('automatic') is setting the observable value.

Try this instead:

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

Either the .bind answer or the function() {} answer will work; but generally I prefer to avoid defining functions in my views where possible, and instead move that logic to the ViewModel.

So another option, and the one I'd probably go with in this case is to define a viewModel.setToManual() function and a viewModel.setToAutomatic() function.

Then the binding handler would just be

click: setToAutomatic

Not only is that cleaner in the view, but it protects the view against changes to the ViewModel's structure as well, as long as the behavior of setToAutomatic (and probably a comparable isAutomatic) are preserved.

发布评论

评论列表(0)

  1. 暂无评论