1

Hi i have two view models and i want to transfer a value between them. here is js fiddle

`http://jsfiddle.net/sohimohit/e84u8L85/`

i want when a user click on show another div button then corresponding item name should be display on another div . means i want to show one viewmodel value into another. secondly when a user click on show another div button another div appears i want an option of cancel so that user can go back to firstdiv. how can i achieve this.

Muhammad Raheel
  • 19,823
  • 7
  • 67
  • 103
user2142786
  • 1,484
  • 9
  • 41
  • 74

2 Answers2

3

You can use global variables container1VM and container2VM for it.
E.g. call of

 container1VM.isVisible(!container1VM.isVisible());
 container2VM.isVisible(!container2VM.isVisible());  

will make visible container - invisible.

JSFiddle DEMO

Code:

HTML:

   <div id="container1">


       <div data-bind="visible: !isVisible()">
        <ul >
            <li >Container1 item</li>
            <!-- ko foreach: myItems -->
            <li>Item <span data-bind="text: $data"></span></li>
            <button data-bind="click:$root.showDiv">show another div</button>
            <!-- /ko -->
        </ul>

       </div>
    </div>
     <div id="container2" data-bind="visible:isVisible">
        <ul>
            <li >Container2 item</li>
            <!-- ko foreach: myItems -->
                <li>Item <span data-bind="text: $data"></span></li>
            <!-- /ko -->
        </ul>
         <button data-bind="click:$root.cancel">cancel</button> 
    </div>   

Javascript:

function Container1ViewModel()
{
    var self = this;
    self.isVisible = ko.observable(false);
    self.showDiv = changeVisibility;
    self.myItems = ko.observableArray();
    self.myItems.push("ABC");
    self.myItems.push("CDE");

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

function changeVisibility()
{
   container1VM.isVisible(!container1VM.isVisible());
   container2VM.isVisible(!container2VM.isVisible());
}

var container1VM = new Container1ViewModel();;
var container2VM = new Container2ViewModel();;

ko.applyBindings(container1VM, document.getElementById("container1"));

ko.applyBindings(container2VM, document.getElementById("container2"));
Ilya
  • 29,135
  • 19
  • 110
  • 158
  • But how can i pass the value of item to second view model suppose i click on show another div button below list item ABC and how can i display value ABC to second viewmodel – user2142786 Aug 19 '14 at 06:43
  • @user2142786 in the same way. E.g. `container2VM.myItems(container2VM.myItems().concat(container1VM.myItems()));` will add all items from VM2 to VM1 – Ilya Aug 19 '14 at 06:53
  • It will add the all items into container2VM but i want that particular item on which i click showAnotherDiv. like ABC then ABC appears in 2nd Viewmodel .FOr this i have to use $root on click ?? – user2142786 Aug 19 '14 at 07:23
  • @user2142786 you can pass `$data` to function as argument. Check http://jsfiddle.net/wv02y4Lt/ – Ilya Aug 19 '14 at 07:55
  • Thanks a lot llya... it works now... i am new bie in knockout js dont know much about it... thanks a lot for your help :) – user2142786 Aug 19 '14 at 08:21
  • Hi llya , here is my fiddle http://jsfiddle.net/sohimohit/43zkoszu/9/ when i click on add fields a form appears i put required validation on name but it is not working can you look into this and guide me – user2142786 Aug 20 '14 at 06:08
  • @user2142786 please, create new question. This will be helpful for other users with same problem – Ilya Aug 20 '14 at 08:01
  • @llya here it is http://stackoverflow.com/questions/25400794/validation-in-knockout-js-input-fields – user2142786 Aug 20 '14 at 09:07
  • @ llya http://stackoverflow.com/questions/25542877/how-to-use-if-in-a-function-in-knockout-js can you answer my this question – user2142786 Aug 28 '14 at 08:31
3

Also consider using Knockout Postbox by the excellent Ryan Niemeyer: https://github.com/rniemeyer/knockout-postbox

You could use syncWith to update an observable controlling visibility. That way both viewmodels don't need to know about each other and you're not hard coding references to your viewmodels.

syncWith - syncWith(topic, [initializeWithLatestValue], [skipInitialPublish], [equalityComparer])

The syncWith function tells an observable to both subscribe and publish on a topic. This allows observables in two different view models to stay in sync with each other without having direct knowledge of its counterpart.

//subscribe to and publish on a topic
this.value = ko.observable(value).syncWith("mytopic");

//subscribe to and publish on a topic and use the last published value to initialize the     observable
this.value = ko.observable().syncWith("mytopic", true);

//subscribe to and publish on a topic, but do not publish out the observable's value initially
this.value = ko.observable(value).syncWith("mytopic", false, true);

//subscribe to and publish on a topic, but only publish when the comparer function returns false
var comparer = function(newValue, oldValue) {
    return newValue < oldValue;
};

this.value = ko.observable(value).syncWith("mytopic", false, false, comparer);
79IT
  • 425
  • 4
  • 9