Reputation: 41605
I'm following the approach suggested on this answer to deal with multiple viewModels and use them in different parts of my page.
Some viewmodels will be used in multiple parts of the page and different elements so I prefer not to use the second suggested solution that recommends applying viewmodels to certain DOM elements.
So I have something like this:
window.masterVM = {
vmA : new VmA(),
vmB : new VmB(),
vmC : new VmC(),
}
ko.applyBindings(masterVM, $(':root').get(0));
Now, on my HTML I do these kind of things:
<div data-bind="click: masterVM.vmA.demo">Click</div>
<div data-bind="click: masterVM.vmC.demo">Click</div>
This makes it accessible in the window object for anyone who want to execute those methods by just doing: window.masterVM.vmC.demo()
.
Is there any way to hide this an encapsulate it in a way that it is not accessible from the outside?
Upvotes: 0
Views: 54
Reputation: 134601
The object masterVM
refers to is your viewmodel. In the context of a binding, you will always have access to the root viewmodel through the $root
binding context.
Your bindings could then be:
<div data-bind="click: $root.vmA.demo">Click</div>
<div data-bind="click: $root.vmC.demo">Click</div>
Then you could just get rid of the use of the global variables.
Upvotes: 1
Reputation: 10500
Not sure if that's what you're looking for, but you can simply pass an anonymous object.
For example:
var VmA = function () { this.demo = _ => console.log('VmA'); }
var VmB = function () { this.demo = _ => console.log('VmB'); }
var VmC = function () { this.demo = _ => console.log('VmC'); }
ko.applyBindings({
vmA : new VmA(),
vmB : new VmB(),
vmC : new VmC(),
}, $(':root').get(0));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-bind="click: vmA.demo">ClickA</div>
<div data-bind="click: vmC.demo">ClickC</div>
Upvotes: 1