| 5 min read
KnockoutJS is a beautiful JavaScript framework that helps you to create responsive and data rich user interface without making the JavaScript code dirty. When you start learning KnockoutJS, you tend to make habit of creating single a View Model and binding it globally or to one particular DOM and play with it.
Once you start diving deep, you will realize, single view model is not enough for developing enterprise applications. It does not help you maintaining the modularity of an application. Bigger the application gets, complexity of the view model increases. You will literally give up as the code will become hard to maintain and even harder to test.
Why one should use multiple view models? Answer is simple, it maintains the modularity. Multiple view models act as modules. You basically divide big problem into small modules which are reusable and easily extensible. You preserve ability to maintain an application by decoupling the components to the most granular level. The app flow becomes so good with introduction of multiple view models in your app.
However, there is a major and most discussed problem with this approach on KnockoutJS section of StackOverflow, Knockout forums (common question with MVVM pattern in general). The communication between multiple view models. Surprisingly, this problem has not been addressed or discussed at all in KO documentation even though people face it quite often. I end up helping at least couple of KnockoutJS users / developers on Stack Overflow having the same problem.
Yes, we don't have out of the box and easy to use solution on communication between multiple view models which are bound in a single viewport but with different DOM elements like the code below.
var self = this; | |
self.firstName = ko.observable(); | |
self.lastName = ko.observable(); | |
self.fullName = ko.computed(function(){ | |
return self.firstName + " " + self.lastName; | |
}); | |
}; | |
var viewModel2 = function(){ | |
var self = this; | |
self.premium = ko.observable(); | |
}; | |
ko.applyBindings(new viewModel1(), document.getElementById("container1")); | |
ko.applyBindings(new viewModel2(), document.getElementById("container2")); |
There are two correct approaches of maintaining communication between multiple view models.
First way of achieving communication between multiple view models is to introduce master view model.
// view model 1 definition | |
var viewModel1 = function(){ | |
this.firstName = ko.observable("Wrapcode"); | |
this.messageForVM2 = ko.observable("Hello from first view model"); | |
this.message = ko.observable("Hello this is vm1") | |
}; | |
//view model 2 definition | |
var viewModel2 = function(vm1){ | |
this.firstName = ko.observable(vm1.firstName()); | |
this.message = ko.observable(vm1.messageForVM2()); | |
}; | |
//master view model with instances of both the view models. | |
var masterVM = (function(){ | |
this.viewModel1 = new viewModel1(), | |
this.firstName = "Rahul", | |
this.viewModel2 = new viewModel2(this.viewModel1); | |
})(); | |
ko.applyBindings(masterVM) |
Live action on JSFiddle : https://jsfiddle.net/rahulrulez/paxnd6uz/1/