knockout.js - Adding and Updating observables in a part of the ViewModel with Knockout Mapping plugin - Not working -
though might many of similar questions knockout mapping plugin , partial view model updation, did not see issue im facing here reported in searching.
i detail example below in short trying do.
first create view model javascript object using ko mapping plugin's ko.mapping.fromjs
. want update part of view model data receive server. so.
- i convert viewmodel javascript object using
ko.mapping.tojs
- update part of js object data server
- use updated js object update view model using
ko.mapping.fromjs
the problems
- values of observables when first created js object through mapping remain same after update
- if new properties present in server data object, show-up values came with, in updated view model - not update new values in consequent updates.
here simplified example.
the view
<div> <label data-bind="text: maintitle"></label> <div data-bind="with: layer0"> <label>name - </label> <label data-bind="text: name"></label> <label>type - </label> <label data-bind="text: type"></label> </div> </div>
data model used make viewmodel
var datamodel = { maintitle: "main title", layer0:{ itemdetails:{ name:"item1name", type:"type1" }, otherdetails:{ prop1: "prop1value", prop2: "prop2value" } }
this js object datamodel
converted ko view model by
var viewmodel = ko.mapping.fromjs(datamodel);
and applied view above applybindings , displays data expected
now receive js object server
var newjsobjectfromserver = { name: "item2name", description: "item2description" // new property not on first model type: "type2" }
now cannot
viewmodel.layer0.itemdetails(newjsobjectfromserver);
because in viewmodel
created mapping plugin itemdetails
property , not method name
, type
methods
so first extract js object viewmodel
var viewmodeljs = ko.mapping.tojs(viewmodel);
then update part of viewmodeljs
new server data
viewmodeljs.layer0.itemdetails = newjsobjectfromserver;
so viewmodeljs
becomes
{ maintitle: "main title", layer0:{ itemdetails:{ name: "item2name", description: "item2description" // new property type: "type2" }, otherdetails:{ prop1: "prop1value", prop2: "prop2value" } } }
then try update viewmodel by
ko.mapping.fromjs(viewmodeljs , viewmodel);
also tried
ko.mapping.fromjs(viewmodeljs , {}, viewmodel);
but result is
layer0.itemdetails.name()
still "item1"
, layer0.itemdetails.type()
still "type1"
while new observable layer0.itemdetails.description()
present , has value "item2description"
now if repeat updating server returned object
{ name: "item3name", description: "item3desctiption" type: "type3" }
this time values in viewmodel
remain same last time layer0.itemdetails.name()
still "item1"
, layer0.itemdetails.type()
still "type1"
, layer0.itemdetails.description()
still "item2description"
, nothing changes in view.
the complexities of objects handled make necessary me use mapping plugin example simplified portray problem facing. reaching out guide me how part of viewmodel updated data server in above exact scenario. if solved can apply more complex real world scenario facing. in advance.
your ui still bound same viewmodel , running mapping again doesn't refresh it.
you can use different approach create parent view model , set "viewmodel" observable member of parent viewmodel. check out fiddle rushed (but working) example of behavior
http://jsfiddle.net/barryman9000/4sknd/2/
var parentviewmodel = function (data) { var _self = this; _self.data = ko.observable(''); _self.loaddata = function () { _self.data(new viewmodel(data)); }; _self.getnewdata = function (data, item) { _self.data(new viewmodel(newjsobjectfromserver)); }; _self.loaddata(); }; var viewmodel = function (data) { var _self = this; ko.mapping.fromjs(data, {}, _self); _self.data = ko.observable(data); }; ko.applybindings(new parentviewmodel(datamodel));
also, if getnewdata() function makes ajax call data, still refresh ui - that's how use "pattern."
update
some ideas: 1) restructure data it's uniform in cases. otherwise you'll building each of viewmodels differently going cause readability headaches later. http://jsfiddle.net/barryman9000/q5rrr/1/
2) if can't restructure data, ditch mapping plugin , manually. i'd yields cleaner markup , gives more control of data. http://jsfiddle.net/barryman9000/5dd27/
Comments
Post a Comment