Reputation: 1799
I am having hell of a time organizing my JS file with multiple viewModels. It is a complete mess and I keep getting errors about binding multiple times, despite having read and tried every trick possible.
Here is my situation: I have 3 view models. 2 of them make ajax request on load. I have also added the stopBinding
handler so i can bind multiple viewModels in the same page. It works... somewhat. I would also like to figure a way to share functions between viewModels. isDirty()
in particular (described here: http://www.knockmeout.net/2011/05/creating-smart-dirty-flag-in-knockoutjs.html)
My file is quiet large, so I will post an example. Everything was implemented according to http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html
JS
ko.bindingHandlers.stopBinding = {
init: function() {
return { controlsDescendantBindings: true };
}
};
ko.virtualElements.allowedBindings.stopBinding = true;
// viewModelOne
$.getJSON('/admin/getusers.json', function(json, status) {
var viewModelOne = ko.mapping.fromJS(json);
// MODE CODE AND FUNCTIONS HERE. SOME OF THEM ARE
// THE SAME AS viewModelTwo USES
ko.applyBindings(viewModelOne, $('#users-section')[0])
});
// viewModelTwo
$.getJSON('/admin/getdeployments.json', function(json, status) {
var viewModelTwo = ko.mapping.fromJS(json);
// MODE CODE AND FUNCTIONS HERE. SOME OF THEM ARE
// THE SAME AS viewModelOne USES
ko.applyBindings(viewModelTwo, $('#deployments-section')[0])
});
// viewModelThree
var viewModelThree = {
someFunction: function() {
// SOME CODE HERE
}
}
ko.applyBindings(viewModelThree, $('#logs-section')[0]);
HTML
<section>
<!-- ko stopBinding: true -->
<div id="deployments-section">
// HTML HERE
</div>
<!-- /ko -->
<!-- ko stopBinding: true -->
<div id="users-section">
// HTML HERE
</div>
<!-- /ko -->
<!-- ko stopBinding: true -->
<div id="logs-section">
// HTML HERE
</div>
<!-- /ko -->
</section>
I do not really need the viewModelTwo
(the user.json
data) to load on initial load, just when i click on a particular link, so the only data I need right away is viewModelOne
(getdeployments.json
data).
I would like to share some functions between viewModels
For some strange reason things break if i do ko.applyBindings(viewModelOne)
to bind this viewModel to the entire document and remove <!-- ko stopBinding --><!-- /ko -->
around <div id="deployments-section"></div>
. It only works the way I posted above.
I get an error about multiple bindings here ko.applyBindings(viewModelOne, $('#users-section')[0])
. Adding ko.cleanNode($('#users-section'))
does not help. I only get the error from this one particular binding, but not the other two.
I guess I'm open to consolidate everything into a single viewModel, if thats a better approach
Upvotes: 0
Views: 509
Reputation:
what about get rid of stopBinding and go back to basic.
Javascript
var vm = {
viewModelOne: ko.observable(),
viewModelTwo: ko.observable(),
viewModelThree: {
someFunction: function() { /* ... */ }
}
};
var shared_functions = {
func1: function() { /* use "this" pointer as if it's object viewModelOne or viewModelTwo */ },
func2: function() {}
};
ko.applyBindings(vm);
// viewModelOne
$.getJSON('/admin/getusers.json', function(json, status) {
var viewModelOne = ko.mapping.fromJS(json);
// MODE CODE AND FUNCTIONS HERE.
// add shared functions too
$.extend(viewModelOne, shared_functions);
vm.viewModelOne(viewModelOne);
});
// viewModelTwo
$.getJSON('/admin/getdeployments.json', function(json, status) {
var viewModelTwo = ko.mapping.fromJS(json);
// MODE CODE AND FUNCTIONS HERE.
// add shared functions too
$.extend(viewModelTwo, shared_functions);
vm.viewModelTwo(viewModelTwo);
});
HTML
<section>
<div id="deployments-section" data-bind="with: viewModelTwo">
// HTML HERE
</div>
<div id="users-section" data-bind="with: viewModelOne">
// HTML HERE
</div>
<div id="logs-section" data-bind="with: viewModelThree">
// HTML HERE
</div>
</section>
If you want some framework level support, besides durandaljs (which I never tried), there is smaller http://pagerjs.com which supports me really well on middle scale knockout web apps.
Upvotes: 1