问题
I'm using backbone for a reasonably complicated form. I have a number of nested models, and have been computing other variables in the parent model like so:
// INSIDE PARENT MODEL
computedValue: function () {
var value = this.get('childModel').get('childModelProperty');
return value;
}
This seems to work fine for keeping my UI in sync, but as soon as I call
.save()
on the parent model, I get:
Uncaught TypeError: Object #<Object> has no method 'get'
It seems that the child model kind of temporarily stops responding.
Am I doing something inherently wrong?
EDIT: The stack trace is:
Uncaught TypeError: Object #<Object> has no method 'get' publish.js:90
Backbone.Model.extend.neutralDivisionComputer publish.js:90
Backbone.Model.extend.setNeutralComputed publish.js:39
Backbone.Events.trigger backbone.js:163
_.extend.change backbone.js:473
_.extend.set backbone.js:314
_.extend.save.options.success backbone.js:385
f.Callbacks.o jquery.min.js:2
f.Callbacks.p.fireWith jquery.min.js:2
w jquery.min.js:4
f.support.ajax.f.ajaxTransport.send.d
EDIT #2 in response to comment below:
There's something basic I'm still not getting. I replaced a few references to this.get('childModel')['childModelProperty'] and now I get things like 'cannot read property childModelProperty of undefined.
I'm not yet pulling anything from the server, the parent model is just created like
define(['jquery', 'underscore', 'backbone', 'models/childmodel'], function($, _, Backbone, ChildModel) {
var ParentModel = Backbone.Model.extend({
defaults: {
childModel : new ChildModel()
}
回答1:
defaults are only used when you create the model. After save is called, it will call set which will overwrite childModel with a simple javascript object. As I see it you have a couple options:
1) use Backbone.Relational
2) override set in each parent model to update the existing child model (or create it) something like the following:
children:{
childModel: ChildModel
}
set: function (key, value, options) {
var attrs;
if (_.isObject(key) || key == null) {
attrs = key;
options = value;
} else {
attrs = {};
attrs[key] = value;
}
_.each(this.children, function (childType, name) {
if (!attrs.hasOwnProperty(name))
return;
//assume the child is just a model--not a collection
var newValue = attrs[name];
delete attrs[name];
var isModel = this[name] && this[name].set;
if (isModel && newValue) {
this[name].set(newValue, options);
}
else if (newValue) {
this[name] = new childType(newValue);
}
else {
delete this[name];
}
this.trigger('change:' + name);
}, this);
return Backbone.Model.prototype.set.call(this, attrs, options);
}
回答2:
Sometimes your childModel does not contains a Backbone.Model, like you were assigned other kind of object.
To avoid the error do this(and also in your console you will get helpful information about the value of that wrong childModel):
computedValue: function () {
var value;
if( this.get('childModel') instanceof Backbone.Model ){
value = this.get('childModel').get('childModelProperty');
}else{
console.log('This is weird, childModel is not a Backbone.Model', this.get('childModel') );
}
return value;
}
来源:https://stackoverflow.com/questions/11364615/no-method-get-on-backbone-model-save