KnockoutJS - Update ViewModel / Mapping Plugin
Asked Answered
P

2

9

How can i update the complete viewModel ?

  1. On page load i get a Model and convert that using ko.mapping.fromJS(myObject) to a viewModel.
  2. If the user clicks a button i want to get updated data from the server
  3. Now i want to apply theese updates

If i use ko.applyBindings(viewModel); it updates the ui perfectly. But it adds the same events again. So if the user clicks the button, the event gets fired twice, third and so on.

Question

What is a good way to update my complete viewModel. Maybe i remove the bindings and apply them again ? (how to do this).

Sample

var viewModel;

function update() 
{
    $.ajax({
        url: '...',
        type: "GET",
        statusCode: {
            200: function (data) {
                 viewModel = ko.mapping.fromJS(data);
                 ko.applyBindings(viewModel);
            }
        }
    });    
}

// first call after page load
update();

// user click
$("#myButton").click(function() {
    update(); 
});

Update

Steve Greatrex Could you post your custom binding implementation?

ko.bindingHandlers.domBinding = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        viewModel.domElement = element;
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        viewModel.domElement = element;
    },
};
Pigtail answered 2/8, 2012 at 13:37 Comment(1)
Could you post your viewModel code as well? Is domElement an observable?Courteous
C
10

If you look at the 'Specifying the update target' on the mapping documentation, you can specify a target for the mapping.

This should mean that you can say:

if (!viewModel)
   viewModel = ko.mapping.fromJS(data);
else
   ko.mapping.fromJS(data, {}, viewModel); 

This way you will create a view model on the initial load, then update that view model for any subsequent loads.

Courteous answered 2/8, 2012 at 13:43 Comment(7)
+1 This works nice. But one thing does not work. I have a customBinding and this does not get updated (stopped working). Any idea ?Pigtail
Could you post your custom binding implementation?Courteous
@dknaack: Make sure you don't call ko.applyBindings a second time. You should only ever call that once per view.Rotten
Can you give me an example of how you then data-bind? ex: data-bind="viewModel" ?Inequity
@Inequity you wouldn't need to change your data bindings after the update - they would automatically be updatedCourteous
@SteveGreatrex gotcha, I'm still having issues with this. I'm using GET, no data at the start, knockout tells my model is undefined. I created a Model for it and tried your method, but my model never gets updated.Inequity
You'll need some form of data up-front to allow you to bind to the initial values. I would suggest creating an "empty" data object that you use with ko.mapping.fromJS as soon as the page loads, then populate it with real data once the AJAX call completesCourteous
M
3

Using mapping plugin I did this

ko.mapping.fromJS(JsonResponse, myObservable());

That's all.

Mop answered 27/9, 2012 at 17:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.