0

On Page load I am converting a JSON data to view model like this

var jsonField = '#' + '<% = hdnField.ClientID  %>';

                    jsonModel= {
                       availables: ko.observableArray([])
                   };

                 
                   var valueField = $(jsonField)[0].value;
                   var arrayGroup = $.parseJSON(valueField);

                   jsonModel.availables = ko.viewmodel.fromModel(arrayGroup);
                  
                  var block=$('#availabilitiesBlock')[0];
                   ko.applyBindings(jsonModel,block);

After the page has loaded, I am calling an ajax server function to update this view model.

In tha ajax success call back I have written like

 var updatedModel = {
                availables: ko.observableArray([])

            };
            updatedModel.availables = ko.viewmodel.fromModel(data.d);

When I try to update the view model with this updated model my entire model becomes blank

I tried the following methods

  1. Pushed data.d into the oldModel.availables observable. When i push the data, the aray objects are not getting converted as observables, but the items got added to the availables array. Whereas in the initial (while page load), the objects got converted without issues.

  2. Tried to update viewmodels directly and in this case entire model becomes blank

    ko.viewmodel.updateFromModel(oldModel, updatedModel);

Snip of Old Model

Old Model

Snip of Updated Model

Updated Model

As I said , when I pushed the array objects directly (data.d), the observables are not getting created automatically as in the first case before ajax.

Why is this happening when the logic is same? I am using http://coderenaissance.github.io/knockout.viewmodel/ for mapping objects automatically.

Any pointers will be helpful

Community
  • 1
  • 1
Rohith Nair
  • 1,080
  • 1
  • 17
  • 33

1 Answers1

3

Rohith, the answer here will depend on what you're returning in from your ajax call.

Instead of creating updateModel, I believe in the return from your ajax call you want

ko.viewModel.updateModel(jsonModel.availables, data.d);

If your data.d returned from the Ajax call doesn't need any special mapping (i.e. its just an array of objects that don't need observables) you can simply update your model directly

//ko.viewModel.updateModel(jsonModel.availables, data.d);
jsonModel.availables(data.d);

The underlying problem that you're running into is that you've been losing the observable to which your view is bound. You're losing jsonModel.availables by overwriting it, or by ignoring it and updating a different model (updateModel in this case).

I'm working on a blog post about this exact issue when working with AJAX, but you can see part of the problem you're having in the third section of this post : http://ryanrahlf.com/getting-started-with-knockout-js-3-things-to-know-on-day-one/

I hope this helps!

Ryan Rahlf
  • 1,772
  • 1
  • 14
  • 15
  • spot on :) I ended up using ko.viewModel.updateModel(jsonModel.availables, data.d); but that causes my UI to hang because of longer script running time – Rohith Nair Jul 09 '13 at 17:08
  • When you see a long running time when changing an observable array, check for complex processes that run on each element (custom bindings?), or knockout computeds that are being re-calculated for each item. – Ryan Rahlf Jul 09 '13 at 19:16
  • @RyanRahlf Would this work with the mapping plugin? I find that I need to call the the applybindings inside the callback of my ajax. Otherwise, the model does not update. I think the mapping pluging breaks the subscribed elements and it cannot update it. http://stackoverflow.com/questions/21558075/how-do-i-update-my-model-using-ajax-and-mapping-plugin/21568045#21568045 – Vyache Feb 05 '14 at 05:04
  • @Vyache, you shouldn't need to call applyBindings again after an ajax call. This blog post might help : http://ryanrahlf.com/knockout-js-observablearray-not-updating-the-ui-heres-how-to-fix-it/ – Ryan Rahlf Feb 05 '14 at 20:21