I have run into the case where I am having to use multiple ViewModels in the same view. I achieved that by using this kind of trick which allows multiple bindings on different items of the DOM:
ko.applyBindings(supervisors, $('#supervisorContainer')[0]);
ko.applyBindings(permits, $('#permitContainer')[0]);
On previous views, I only had to bind one mini object, like a PeopleModel. Now as other pages are getting more complex, I feel as though the better way to do it would be to encapsulate these smaller models inside of the larger main model as arrays. I haven't seen any examples of this around, so let's say we have a project. In this project there are many supervisors and many permits. Supervisors and permits are observable arrays. Right now I have them each both as their own model, but conceptually it might make more sense for the one and only model to be the ProjectModel, and then to have Supervisors and Permits as arrays inside of that model.
Using an example right from the Knockout.JS website, I don't see how something like this could be converted to be a ProjectModel with multiple arrays inside, mainly because of the language, such as how gifts
are passed to the function.
var GiftModel = function(gifts) {
var self = this;
self.gifts = ko.observableArray(gifts);
self.addGift = function() {
self.gifts.push({
name: "",
price: ""
});
};
self.removeGift = function(gift) {
self.gifts.remove(gift);
};
};
var viewModel = new GiftModel([
// Data goes in here
]);
ko.applyBindings(viewModel);
Is this way of thinking correct? Or is there a better way? The following code does actually seem to work with my foreach loops in the view:
var ProjectModel = function(supervisors, permits) {
var self = this;
self.supervisors = ko.observableArray(supervisors);
self.permits = ko.observableArray(permits);
self.addPermit = function() {
self.permits.push({
number: "",
date: ""
});
};
self.removePermit = function(permit) {
self.permits.remove(permit);
};
self.addSupervisor = function() {
self.supervisors.push({
name: "",
number: ""
});
};
self.removeSupervisor = function(supervisor) {
self.supervisors.remove(supervisor);
};
};
var viewModel = new ProjectModel(supervisorJSONArray,permitJSONArray);
ko.applyBindings(viewModel);
You've really 'melded' the two viewModels together... instead I would 'composite' them together, something like this:
You could then use 'with' statements in the view to reference the appropriate view model.