Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout.js - How to change the viewmodel

I'm trying to change the view model which is bound to some part of a DOM template (instead of changing the values of the view model) but I just can't figure out how or if it's even possible

Here's the scenario:

  • Create a new View Model object
  • Bind it (e.g. applyBindings(myViewModel)
  • Create another View Model object
  • Bind the new object to the same part of the DOM so all elements are now bound to the new object.

I want to do the equivalent of changing the value of DataContext of a control in WPF (on which KO's MVVM pattern is based)

The reason for this is that I'm trying to use the same view model for both the representation of the object in a list and the representation of the object in its own view, so I already have a view model for all objects being shown in the list.

There are other workarounds but I think this would be the most elegant way to do it.

like image 934
Juan Campa Avatar asked Dec 26 '12 05:12

Juan Campa


2 Answers

There are two way of working with multiple viewmodel. The first way is to do multiple binding like @nathan gonzalez said. You should do binding up your viewmodels. However this complicates things a bit. Therefore difficult to manage.

The second way is to use master viewmodel. I would recommend this.

http://jsfiddle.net/sinanakyazici/e29EZ/10/

<div data-bind="with: mainvm">
    <span data-bind="text: prop, click : action"></span>
</div>

var vm = function(value)
{
    this.prop = ko.observable(value);
    var self = this;
    this.action = function() {
        console.log("clicked: " + self.prop());
    }
}

var master = {
    mainvm : ko.observable(null)
}

master.mainvm(new vm('viewmodel 1'));
master.mainvm(new vm('viewmodel 2'));
ko.applyBindings(master);
like image 143
sinanakyazici Avatar answered Sep 28 '22 04:09

sinanakyazici


so ko.applyBindings() should cover this for you. you can pass in a 2nd parameter that tells which top level element to apply the bindings to, like so:

 ko.applyBindings(myExistingViewModel, $('#someElementId')[0]);

you may want to clean the elements first though, like this:

ko.cleanNode($('#someElementId')[0]);

this completely removes the bindings and clears the in memory data for that element and its children bindings.

like image 36
nathan gonzalez Avatar answered Sep 28 '22 04:09

nathan gonzalez