Reputation: 1740
I am trying to do a fairly simple partial update. I update a view models' property "person", which is initially null, with an object with its own child property "lastName". This fails with "no method person.lastName()" when trying to notify subscribers.
Fiddle demonstrating the issue: http://jsfiddle.net/P4Jd3/4/
HTML
<body>
<hr/>
<div data-bind="text: rootdata"></div>
<hr/>
<div data-bind="if: person">
<div data-bind="text: person.lastName()?person.lastName()+'###':'foo'">
</div>
</div>
<hr/>
<input type="submit" data-bind="click: updatedata" value="update data"></input>
</body>
JS:
newdata = {
person: {
lastName: "Mr.Bar"
},
rootdata : "Root 2"
}
model = {
self: this,
person : ko.observable(null),
rootdata : ko.observable("Init root"),
updatedata: function() {
ko.mapping.fromJS(newdata, {}, model);
}
}
ko.applyBindings(model);
At the moment of update, I get an error stating that Object function [ko observable junk string] has no method lastName().
Message: TypeError: Object function d(){if(0<arguments.length){if(!d.equalityComparer||!d.equalityComparer(c,arguments[0]))d.H(),c=arguments[0],d.G();return this}b.r.Wa(d);return c} has no method 'lastName';
Bindings value: text: person.lastName()?person.lastName()+'###':'foo'
That person.lastName()+"##" is needed for combining property values with optional text formatting, depending on whether some properties are non-empty.
I am out of ideas on this one.
Upvotes: 0
Views: 114
Reputation: 16688
This is a perfect use-case for the with
binding. If you replace if: person
with with: person
, it simplifies your code and just works:
<div data-bind="with: person">
<div data-bind="text: lastName() ? lastName()+'###' : 'foo'"></div>
</div>
http://jsfiddle.net/mbest/P4Jd3/5/
Upvotes: 2
Reputation: 8331
simply remove the ()
from lastName
property. Because it's not observable property
OR edit your code to define new model for your data with observables properties
Upvotes: 0
Reputation: 5147
Your person object doesn't have a lastname property, let alone an observable when you call applyBindings. It is only created when you call upadteData.
I usually initialise my view model with blank observables:
model = {
self: this,
person : ko.observable({ lastName: ko.observable('')}),
rootdata : ko.observable("Init root"),
updatedata: function() {
ko.mapping.fromJS(newdata, {}, model);
}
}
ko.applyBindings(model);
Upvotes: 3