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.

  1. i convert viewmodel javascript object using ko.mapping.tojs
  2. update part of js object data server
  3. use updated js object update view model using ko.mapping.fromjs

the problems

  1. values of observables when first created js object through mapping remain same after update
  2. 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

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -