Search code examples
knockout.jsknockout-3.0

Knockout.js - Encapsulate View Models and hiding them from outside


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?


Solution

  • 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>