0

How to I replace an entire object(created using mapping plugin) inside the viewmodel with a new one(created using the mapping plugin)? Please note my comment inside the view model...

function viewmodel(objServerModel) {
            var self = this;
            self.profile = objServerModel; //Using ko.observable(objServerModel) doesn't seem to work. I need to replace this object every time I load new content from the server and it should automatically update all controls bound to it. Note that this is the object that is created using ko.mapping.fromJS
            self.devices = ko.observableArray(['one', 'two']);

            });

The below function is only called once. From the next time onwards, I need to just replace self.profile whenever I retrieve new data from the server. If I use self.profile=ko.observable(objServerModel), it doesn't work. How do I replace the profile object inside the viewmodel whenever I load new data from the server asynchronously?

  function ApplyKnockOut() {

            var objServerModel = '@Html.Raw(HttpUtility.JavaScriptStringEncode(clsTest.ReadXmlIntoModel()))'

                var objResult = $.parseJSON(objServerModel);
                var objModelFromServer = ko.mapping.fromJS(objResult);

                var clientViewModel = new viewmodel(objModelFromServer);

                ko.applyBindings(clientViewModel);
                return clientViewModel;

            }

I would appreciate any help.

Thanks

Edit: The replaced mapped models structure will be the same. Only values will differ.

Here is my jsfiddle : http://jsfiddle.net/rzFgU/

Josh
  • 13,530
  • 29
  • 114
  • 159
  • This is by design, it only updates the fields that have changed, so that only the bindings that have changed will update. – Anders Jun 12 '13 at 07:54

1 Answers1

1

Ko mapping works like this by design because it does not want to totally renderer view but rather only update the bindings that have changed. You can do something like this if you really, really want it to change to a new object reference. Note that its important that the member holding the object is an observable since we now change object reference instead of updating observables on the same object.

http://jsfiddle.net/N56FR/

ViewModel = function(data) {
    this.complex = ko.observable(); //Important
    this.map(data);
};

ViewModel.prototype = {
    map: function(data) {
        var mapping = {
            complex: {
                update: function(options) {
                    return ko.mapping.fromJS(options.data);
                }
            }
        };
        ko.mapping.fromJS(data, mapping, this);
    }
};

edit: there are a number problems with your fiddle from below comments jsfiddle.net/rzFgU

I'll list them here

  • Your saying that observable wont work (Its a comment in fiddle code), thats because your doing objectcreatedusingmapping.firstName, you cant access a property on a observable like that. Use the with binding around the input element and then access the firstName directly. Or do objectcreatedusingmapping().firstName. First solution is cleaner.
  • ReplaceModel is haning lose so you cant do data-bind="click: ReplaceModel" either move the function to the model, or do data-bind="click: window.ReplaceModel". First solution is cleaner
  • You are not even using your PersonViewModel, you are creating one and then send that in as argument to the fromJS function, meaning that it will be replaced with a dynamic created object.
Anders
  • 17,306
  • 10
  • 76
  • 144
  • That looks so complicated to me. complex inside map inside viewmodel. Can you please update it on this fiddle : http://jsfiddle.net/rzFgU/ ? – Josh Jun 12 '13 at 12:46
  • 1.) When I changed it to observable, I changed the binding to firstname() as well. – Josh Jun 12 '13 at 14:11
  • im sorry, I tried firstname(), not viewmodel().firstname. I'm still trying some stuff – Josh Jun 12 '13 at 14:15
  • use a 'with' binding instead, its more clean – Anders Jun 12 '13 at 14:15
  • with binding isn't working for me. It doesn't even display the "just" in the textbox. I need to replace the existing object inside the viewmodel with a totally new copy that is retrieved from the server – Josh Jun 12 '13 at 14:33