Knockout.js ko.mapping.toJS does not update data in my opinion

I am retrieving a json object from the server and populating my view. Then I change the data, push it to the server. Then I retrieve a new copy of the data, hoping that it will update my view with any changes. However, this does not happen. TIA

$(document).ready(function() { var customer_id = get_customer_id(); var data = load_model(); contract_model = ko.mapping.fromJS(data,{}); ko.applyBindings(contract_model); } function load_model(){ var url = '/ar/contract_json?contract_id='+get_contract_id(); var data = ''; $.ajax({ type:'GET', url:url, async:false, success: function(returningValue){ data = returningValue; } }); return data; } 

This boot is working fine. Then I do some things and change one of the observed ones and drop the data to the server. The server receives the update, and then I make a new selection of data, so that the view will be updated (I know that I can transfer new data in one step, but this is in code that has not yet been reorganized).

 function refresh_data(contract_model){ var url = '/ar/contract_json?contract_id='+get_contract_id(); $.post(url,function(data){ console.log(data); ko.mapping.fromJS(contract_model,{},data); ko.applyBindings(contract_model); console.log(ko.mapping.toJS(contract_model)) }); } function refresh_data(contract_model){ var url = '/ar/contract_json?contract_id='+get_contract_id(); $.post(url,function(data){ console.log(data); ko.mapping.fromJS(contract_model,{},data); console.log(ko.mapping.toJS(contract_model)) }); } function push_model(contract_model,refresh){ var url = '/ar/update_contract'; var data = {'contract':ko.mapping.toJSON(contract_model)} delete data['lines']; $.post(url,data,function(return_value){ if (refresh){ refresh_data(contract_model); }; }); } 

All console messages show new data, but my view is never updated.

+6
source share
3 answers

I believe the problem is with the order of the parameters that you pass to the ko.mapping.fromJS function when updating contract_model .

You have:

 ko.mapping.fromJS(contract_model,{},data); 

Do you want to:

 ko.mapping.fromJS(data, {}, contract_model); 
+20
source
Answer

@ seth.miller is correct. You can also ignore the middle option, if your contract_model is the same as it was previously mapped. If there are only two arguments, ko.mapping.fromJS checks to see if the second argument has the "__ko_mapping__" property. If so, he sees it as a goal, otherwise he sees it as an object of options.

+2
source

Based on @DBueno's observation - for those using typescript, I highly recommend commenting on this particular overload from your knockout.mapping.d.ts file.

 fromJS(jsObject: any, targetOrOptions: any): any; 

enter image description here

After that, you will get a compile time error:

 ko.mapping.fromJS(item.data, item.target); 

and you can replace it much safer

 ko.mapping.fromJS(item.data, {}, item.target); 

It is item.target was previously displayed or not (and thethefore will have the __ko_mapping__ property), it will always copy the properties.

0
source

Source: https://habr.com/ru/post/908576/


All Articles