Tom Rudge Tom Rudge - 1 month ago 13
Javascript Question

observe KO observable from another viewmodel

So I have two view models taking to each other



var viewModel1 = function(){
this.messageForVM2 = ko.observable("");
this.message = ko.observable("Hello this is vm1")
};

var viewModel2 = function(vm1){
this.message = ko.observable(vm1.messageForVM2());
};


var masterVM = (function(){
this.viewModel1 = new viewModel1(),
this.viewModel2 = new viewModel2(this.viewModel1);
})();

ko.applyBindings(masterVM)

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<h4>View Model 1</h4>
<div data-bind="with: viewModel1">
<p data-bind="text: messageForVM2"></p>
<input data-bind="value: messageForVM2, valueUpdate: 'input'" />
</div>

<h4>View Model 2</h4>
<div data-bind="with: viewModel2">
<!-- ko if: message() === "hello" -->
<p data-bind="text:message"></p>
<!-- /ko -->
</div>





(also over here http://jsfiddle.net/ceryb9pc/)

I want viewmodel2 data-bind to show only if "hello" is the value in the observable in viewmodel1. This works but I want it to work when the value is updated in the viewmodel1 input.

In my example is only works when:

this.messageForVM2 = ko.observable("hello");


but need to remove like:

this.messageForVM2 = ko.observable();

Answer

You need to assign your first viewmodel's Observable to your second viewmodel's message variable. Otherwise it will only be set the first time it loads.

Change:

this.message = ko.observable(vm1.messageForVM2());

To:

this.message = vm1.messageForVM2;

This way, this.message is a reference to vm1.messageForVM2, meaning both variables now share the same value.


var viewModel1 = function(){
    this.messageForVM2 = ko.observable("");
    this.message = ko.observable("Hello this is vm1")
};

var viewModel2 = function(vm1){
    this.message = vm1.messageForVM2;
};


var masterVM = (function(){
    this.viewModel1 =  new viewModel1(),
    this.viewModel2 = new viewModel2(this.viewModel1);
})();

ko.applyBindings(masterVM)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<h4>View Model 1</h4>
<div data-bind="with: viewModel1">
    <p data-bind="text: messageForVM2"></p>
    <input data-bind="value: messageForVM2, valueUpdate: 'input'" placeholder="Enter 'hello' here" />
</div>

<h4>View Model 2</h4>
<div data-bind="with: viewModel2">
    <!-- ko if: message() === "hello" -->
    <p data-bind="text:message"></p>
    <!-- /ko -->
</div>