Reputation: 13843
I'm thinking that my application is getting quite large now, too large to handle each View with a single ViewModel.
So I'm wondering how difficult it would be to create multiple ViewModels and load them all into a single View. With a note that I also need to be able to pass X ViewModel data into Y ViewModel data so the individual ViewModels need to be able to communicate with each other or at least be aware of each other.
For instance I have a <select>
drop down, that select drop down has a selected state which allows me to pass the ID of the selected item in the <select>
to another Ajax call in a separate ViewModel....
Any points on dealing with numerous ViewModels in a single View appreciated :)
Upvotes: 204
Views: 86874
Reputation: 867
We use components to achieve that. (http://knockoutjs.com/documentation/component-overview.html)
For example, we have this component library we are developing: https://github.com/EDMdesigner/knobjs
If you dig into the code, you will see that for example we reuse the knob-button component in several places.
Upvotes: 0
Reputation: 3483
This is my answer after completing very large project with lots of ViewModels in single view.
Html View
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div id="container1">
<ul>
<li >Container1 item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
</div>
<div id="container2">
<ul>
<li >Container2 item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
</div>
<script src="js/jquery-1.11.1.js"></script>
<script src="js/knockout-3.0.0.js"></script>
<script src="js/DataFunction.js"></script>
<script src="js/Container1ViewModel.js"></script>
<script src="js/Container2ViewModel.js"></script>
</body>
</html>
For this view I'm creating 2 view models for id=container1 and id=container2 in two separate javascript files.
Container1ViewModel.js
function Container1ViewModel()
{
var self = this;
self.myItems = ko.observableArray();
self.myItems.push("ABC");
self.myItems.push("CDE");
}
Container2ViewModel.js
function Container2ViewModel() {
var self = this;
self.myItems = ko.observableArray();
self.myItems.push("XYZ");
self.myItems.push("PQR");
}
Then after these 2 viewmodels are registering as separate viewmodels in DataFunction.js
var container1VM;
var container2VM;
$(document).ready(function() {
if ($.isEmptyObject(container1VM)) {
container1VM = new Container1ViewModel();
ko.applyBindings(container1VM, document.getElementById("container1"));
}
if ($.isEmptyObject(container2VM)) {
container2VM = new Container2ViewModel();
ko.applyBindings(container2VM, document.getElementById("container2"));
}
});
Like this you can add any number of viewmodels for separate divs. But make sure do not create separate view model for a div inside registered div.
Upvotes: 24
Reputation: 22298
If they all need to be on the same page, one easy way to do this is to have a master view model containing an array (or property list) of the other view models.
masterVM = {
vmA : new VmA(),
vmB : new VmB(),
vmC : new VmC(),
}
Then your masterVM
can have other properties if needed, for the page itself. Communication between the view models would not be difficult in this situation as you could relay through the masterVM
, or you could use the $parent
/ $root
in bindings, or some other custom options.
Upvotes: 150
Reputation: 4357
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.
For example:
ko.applyBindings(myViewModel, document.getElementById('someElementId'))
This restricts the activation to the element with ID someElementId
and its descendants.
See documentation for more details.
Upvotes: 291
Reputation: 386
Check MultiModels plugin for Knockout JS - https://github.com/sergun/Knockout-MultiModels
Upvotes: 4