Search code examples
knockout.jsjavascriptknockout-mvc

How to pass value from one view model to another viewmodel in knockout js?


i have two view models and i want to pass value from one view model to another viewmodel. i have two viewmodels and two div i want to display another div on click of button which is present in div 1.

here is html code

   <div id="container1">
        <ul >
            <li >Container1 item</li>
            <!-- ko foreach: myItems -->
            <li>Item <span data-bind="text: $data"></span></li>
            <!-- /ko -->
        </ul>
        <button data-bind="click:showDiv">show another div</button>
    </div>
     <div id="container2" data-bind="visible:show">
        <ul>
            <li >Container2 item</li>
            <!-- ko foreach: myItems -->
                <li>Item <span data-bind="text: $data"></span></li>
            <!-- /ko -->
        </ul>
    </div> 

and here is script

function Container1ViewModel()
{
    var self = this;
    self.myItems = ko.observableArray();
    self.myItems.push("ABC");
    self.myItems.push("CDE");

} 
function Container2ViewModel() {
    var self = this;
    self.myItems = ko.observableArray();
    self.myItems.push("XYZ");
    self.myItems.push("PQR");

}


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"));
    }
});

how can i do it ?


Solution

  • You can make use of KO.postbox by the great @RyanNiemeyer

    I introduced one variable in both the viewmodels each

    In viewmodel 1 which will publish (shout) the changes once made :

    self.isVisible = ko.observable(false).publishOn("showDiv");
    

    in viewmodel 2 which will be listning to changes from viewmodel 1

    self.isVisible = ko.observable(false).subscribeTo("showDiv");
    

    Then I created one click method in first viewModel to toggle Show Div action (visible : true / false)

    self.showDiv = function(){
         if(self.isVisible())
             self.isVisible(false);
        else
            self.isVisible(true);
    }
    

    Changed visible binding from your existing markup to this :

    <div id="container2" data-bind="visible:isVisible">
    

    It now publish changes made in first viewmodel to second viewmodel. This is called pub-sub mechanism. Read more on : https://github.com/rniemeyer/knockout-postbox

    Fiddle here : http://jsfiddle.net/rahulrulez/0454h205/1/