Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

splitting up knockoutjs

My app view model is growing very large. How do I properly split it up into files and namespaces? Do I create a second namespace object and have the view model be passed in as a parameter?

var BALL = {};
BALL.roll = function(avm) { // function code };
like image 918
MKaras Avatar asked Feb 09 '12 11:02

MKaras


People also ask

Can we have multiple knockout models on a single page?

Knockout now supports multiple model binding. The ko. applyBindings() method takes an optional parameter - the element and its descendants to which the binding will be activated. This restricts the activation to the element with ID someElementId and its descendants.

How do you activate a KnockoutJS model?

To activate Knockout, add the following line to a <script> block: ko. applyBindings(myViewModel); You can either put the script block at the bottom of your HTML document, or you can put it at the top and wrap the contents in a DOM-ready handler such as jQuery's $ function.

What is KnockoutJS used for?

KnockoutJS is basically a library written in JavaScript, based on MVVM pattern that helps developers build rich and responsive websites.

What is knockout language?

Knockout is a JavaScript library that helps you to create rich, responsive display and editor user interfaces with a clean underlying data model.


1 Answers

My personal preference is not to split up my applyBindings calls and instead work with a single global namespace branch off of this.

My reasoning is that for multiple bindings to work correctly and not conflict you need to be very careful your selected target dom elements do not change. Unfortunately the markup has a nasty habit of changing over time which can get you in trouble with your viewModels later on.

My general approach which i've used on a very large KO project has been

  1. One global top level namespace for the whole app eg myapp
  2. Split up separate functional blocks into separate files. Usually with their own distinct namespace. e.g. `myapp.navigation'
  3. If one namespace in particular gets too big split it into further sub namespaces or if that is not appropriate split the same namespace across multiple files.
  4. Mash all the files at the end to preserve performance.

Some namespace code I've recently been using

var Namespace = (function() {
    var namespace, global, root;

    namespace = function(identifier, contents) {
        if (!identifier || identifier.length == 0) {
            throw Error("A namespace identifier must be supplied");
        }
        global = window;

        // create the namespace
        var parts = identifier.split(".");
        for (var i = 0; i < parts.length; i += 1) {
            if (!global[parts[i]]) {
                global[parts[i]] = {};
            }
            if (i == 0) {
                root = global[parts[i]];
            }
            global = global[parts[i]];
        }

        // assign contents and bind
        if (contents) {
            global.$root = root;
            contents.call(global);
        }
    };

    return namespace;
})();

So in your myapp.navigation file you would have

Namespace("myapp.navigation", function() {
     var self = this; // your myapp.navigation object

     this.someFunction = function() {
     }       
});

This is just shorthand for using a self invoking function to pass in a manually constructed namespace. It gives you a private closure and you are free to use multiple Namespace calls with the same namespace in different js file.

Your applyBindings call can now always be

ko.applyBindings(myapp);

Hope this helps.

like image 148
madcapnmckay Avatar answered Oct 30 '22 08:10

madcapnmckay