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 };
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 };
Share
Improve this question
asked Feb 9, 2012 at 11:43
MKarasMKaras
2,1522 gold badges21 silver badges39 bronze badges
1
- 3 This answer might help you: stackoverflow./questions/8676988/…. It has three options for using multiple view models in Knockout. – RP Niemeyer Commented Feb 9, 2012 at 14:07
1 Answer
Reset to default 11My 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
- One global top level namespace for the whole app eg
myapp
- Split up separate functional blocks into separate files. Usually with their own distinct namespace. e.g. `myapp.navigation'
- 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.
- 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.