msn
msn

Reputation: 13

Load requirejs module with data-bind (knockout.js)?

What I want to do is load js using the data-bind attribute. I am fairly new to requirejs and knockout and I'm not sure how to go out this.

Right now I have my js split into different require modules for each type of component I have. For example, I have a file that deals with the header dropdown (header.js):

 define('headerDropdown',['jquery', 'bootstrap']),function(jquery, bootstrap){
     var $menu = $(".menu");
     var $dropdown = $menu.find("ul");
    $menu.on("click", function () {
       $dropdown.toggle("fast");
    });
 };     

What I want to do is:

<div class="header" data-bind="headerDropdown">...</div>

And load the respective js.

Most of my js modules are UI changes based on clicks (show and hiding stuff on click) but I only want the js to load is the html block is on the page.

Hopefully this makes sense!

How can I do this using requirejs and knockout?

Upvotes: 0

Views: 1042

Answers (1)

jparaya
jparaya

Reputation: 1339

Looks like you are mixing concepts. First let's see the define() definition (suppose the file is headerDropdown.js):

define('headerDropdown',['jquery', 'bootstrap']),function(jquery, bootstrap){
     var $menu = $(".menu");
     var $dropdown = $menu.find("ul");
    $menu.on("click", function () {
       $dropdown.toggle("fast");
    });
 };     
  1. Require.js does not recommend to define a module expliciting their name ('headerDropdown'); you can get the name based on the filename. That's because require has a tool for optimization of the javascript in production: you can concatenate and minimize the output JS. The optimizer uses the filename to define the module name. Please, avoid defining with name.

  2. If you look at the code, you are requiring ['jquery'] but inside the module definition you're using the global jQuery variable. That's OK because jQuery define their module as a global variable, but the convention is to receive in the function the jquery reference:

    define('headerDropdown',['jquery', 'bootstrap']),function($, bootstrap)

  3. You are defining a module that manipulates DOM directly, which goes against the DOM update procedure of knockout. In your case, you are using a data-bing="headerDropwodn" so the headerDropdown is a bindingHandler rather than a simple module. Please check: http://knockoutjs.com/documentation/custom-bindings.html

  4. You can load on require as you pointed on the question. You just need to change your codes:

    • Load in your HTML an app.js script (for example). This app.js requires knockout and your headerDropdown bindingHandler. In the function declaration you define the ko.applyBindings and that's all.

Greetings!

Upvotes: 1

Related Questions