Question

I'm having an issue applying custom binding handlers when using knockout with requireJS. Basically, in the past I've included a global binding-handler js file that contains all my custom bindings. Now that I'm using requireJS to enforce dependencies, I'm not sure how to access these custom bindings.

I used to do create the global functions with

function KOCustomBindings() {
// Custom Bindings
ko.bindingHandlers.returnKey = {
//handler code
}
}

Now that I'm using require, I feel as if I should have a define statement

define(['jquery', 'knockout'],
    function($, ko)){
// Custom Bindings
return KOCustomBindings;
}
});

However, I don't believe the bindings will execute unless specifically called, perhaps in a shim? Does anyone have any ideas on this?

Thanks for your help,

Était-ce utile?

La solution

Since custom bindings modify the ko object, they only need to be loaded once, and their modules do not need to return anything. If you have a main/entry/app section as the first step in your app, simply requiring your custom bindings and extenders is all you need to do.

define(['jquery', 'knockout'], function($, ko)){
    // Custom Bindings
    ko.bindingHandlers.returnKey = { ... }

    //NO return needed
});

Then, in your startup section, just

require('lib/custom-ko-bindings');

Autres conseils

An easy way to do this is to define your custom binding as an AMD module and require it from your parent viewmodel. Example -

Bindings.js

define(, function () {
    ko.bindingHandlers.Date = {
        update: function (element, valueAccessor) {
            var value = valueAccessor();
            var date = moment(value());
            var strDate = date.format('MM-DD-YYYY');
            $(element).text(strDate);
        }
    };
});

Your viewmodel -

define(['jquery', 'knockout', 'bindings'],
    function($, ko, bindings)){
});

This will give any element in your DOM access to the Knockout binding handler of 'Date' for example. (My example is one that I have used with moment.js)

In any child views or views that require your parent view model now you should be able to use

<span data-bind="Date: myDate" />

I was able to achieve this by wrapping knockout in my bindings module and returning the modified knockout instance. Here is the config I ended up with:

require.config({
  paths: {
    'knockout': 'lib/knockout', // name that's only used once in customBindings.js
    'ko': 'app/customBindings'
  }
  // more config ommitted
});

My custom bindings:

define(['knockout'], function (ko) {
    ko.bindingHandlers.returnKey = {
        //handler code
    }
    return ko;
});

And my modules that require knockout only need to reference 'ko'.

require(['jquery', 'ko', 'underscore'], function ($, ko, _) {
    // do knockout-y things! now with bindings!
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top