Knockout custom binding update not firing
Asked Answered
T

1

17

With the following code, I would expect my update function to execute every time the viewModel.item observable is updated. I can see my init and update functions firing on page load as expected, but not when my button is clicked which updates the observable's value.

Markup:

<button id='addButton'>item++</button>
<br/>
<span>viewModel.item = </span>
<span data-bind='text: $data.item(), bind: viewModel.item'></span>

Script:

$(document).ready(function() {
    $('#addButton').click(function() {
        viewModel.item(viewModel.item() + 1);
    });    
    var viewModel = {
        item: ko.observable(1)
    };        
    ko.bindingHandlers.bind = {
        init: function(element, valueAccessor) {
            alert('init');
        },
        update: function(element, valueAccessor) {
            alert('update');
        }  
    };        
    ko.applyBindings(viewModel);
}); 

I've browsed some of the similar questions and haven't found a comparable example. I've created a JSFiddle here.

Toughminded answered 26/5, 2014 at 22:56 Comment(2)
What is the expected behavior? An alert that says update on every click of the button?Joel
That's exactly right.Toughminded
A
32

The update function of a binding handler will run whenever the observables it accesses are updated. Your function doesn't access any observables.

Here is an updated version that will work:

ko.bindingHandlers.bind = {
    init: function(element, valueAccessor) {
        alert('init');
    },
    update: function(element, valueAccessor) {
        ko.unwrap(valueAccessor());
        alert('update');
    } 
};        

http://jsfiddle.net/vMD74/14/

Attaint answered 27/5, 2014 at 2:1 Comment(3)
Why call to valueAccessor() don't solve the problem, but ko.unwrap(valueAccessor()) do?Peak
I see. The valueAccessor()() just works. Ok. ko.unwrap(valueAccessor()) the only scalable solution.Peak
valueAccessor() just returns the value that was set to the binding (it's a computed that wraps the expression in the binding). So valueAccessor() doesn't actually access the observable, so no dependency is creatd. valueAccessor()() gets the binding's value AND accesses the observable, creating the dependency. ko.unwrap() returns a de-refernced observable or the literal object itself if the parameter to unwrap() is just a plain old object.Denison

© 2022 - 2024 — McMap. All rights reserved.