Dirk Boer
Dirk Boer

Reputation: 9123

Knockout.js binding scope

What is the best way to share a variable between the init and the update part of a bindinghandler?

ko.bindingHandlers.someBinding = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) 
    {
        // declare something here
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) 
    {
        // use the variable here
    }   
}

I know for sure that I don't want to pollute the view model itself. I could attach it to the element by jQuery.data() but that feels pretty ugly.

Upvotes: 3

Views: 473

Answers (1)

krivtom
krivtom

Reputation: 24916

The custom binding in knockout.js is only created once, so this means that if you store some local variable it will be re-used for every element where the binding is used. If this is not an issue for you below is one way how to achieve that.

Knockout binding requires that you return an object that has methods init and update. You can use object literal as you showed in your sample, but you can use other patterns, for example revealing module pattern:

// instead of using object literal, use IIFE (immediately invoked function expression:
ko.bindingHandlers.someBinding = (function(){
     // define your local variables, functions and anything else you need
     // keep in mind that the same variables will be re-used for EVERY
     //element where the binding is used
     var yourVariable = 0,

         // declare init and update methods
         init = function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) 
         {
            alert(yourVariable);   // displays 0
            yourVariable += 1;
         },
         update = function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) 
         {
            alert(yourVariable);   // displays 1
         };
    // return object literal with methods init and update
    return {
        init: init,
        update: update
    };
}());    // execute the function

Upvotes: 4

Related Questions