我遇到了在获取后将从服务器收到的JSON数据与我的视图同步的问题。
我没有“mainmodel”的集合,因为我一次只使用一个“mainmodel”但是很多“mymodel”,无论如何,结构如下:
var mymodel = Backbone.Model.extend({
defaults: {k1:"",
k2:"",
k3:""}
});
var collection = Backbone.Collection.extend({model:mymodel,});
var mainmodel = Backbone.Model.extend({
defaults: {v1:"",
v2:"",
v3:"",
v4:new collection()
});
我从父视图中的渲染功能创建“mymodel”的嵌套视图。这有效......,只有当我使用新模型时。
// My ParentView render function
render: function() {
for (var i = 0; i < this.model.v4.length;i++) {
var view = new MyModelView({model:this.model.v4.at(i)});
this.$el.append($(view.render().el));
}
this.$el.append(this.template(this.model.toJSON()));
return this;
},
// The MyModelView render function below
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
现在,如果我打开我的应用程序并从那里创建模型,上面的工作就可以了。但是,如果我打开我的应用程序并提供一个id,我将获取服务器,检索数据,并创建一个新的ParentView我最终得到一个错误,上面写着“this.model.v4.at not a function”。啊。
现在,如果我将FIRST渲染功能更改为,将at(i)更改为[i]
var view = new MyModelView({model:this.model.v4[i]});
并将第二个渲染函数(删除toJSON)更改为:
this.$el.html(this.template(this.model));
它呈现。但我仍然无法在没有错误的情况下移动视图。没有惊喜。 我使用过console.log(JSON.stringify(this.model));因为他们到达了parentView和MyModelView。返回的JSON看起来像这样,无论是获取还是创建。
{"v1":"val1",
"v2":"val2,
"v3":"val3",
"v4":[{"k1":"key1","k2":"key2","k3","key"}, { ... }, { ... }]
}
JSON数据结构看起来完全相同。我认为JSON格式不正确,所以我在将模型交给视图之前尝试使用JSON.parse,但这不起作用。也许我离开了,但我原本以为我有一个JSON格式问题,但现在我不知道。服务器将内容返回为'application / json'。
编辑:v1,v2,v3的JSON值正确呈现。
有什么想法吗?
答案 0 :(得分:3)
你有两个问题:一个你知道,一个你不知道。
您知道的问题是,您的mainmodel
不会自动将v4
JSON转换为集合,因此您最终会得到一个阵列,您希望收集该集合。您可以通过向mainmodel
添加parse
来解决此问题:
parse: function(response) {
if(response.v4)
response.v4 = new collection(response.v4);
return response;
}
您不知道的问题是defaults
中的mainmodel
有隐藏的引用分享问题:
var mainmodel = Backbone.Model.extend({
defaults: {
//...
v4: new collection()
}
});
您在Backbone.Model.extend
对象中定义的任何内容都会在模型的原型上结束,因此整个defaults
对象由模型的所有实例共享。此外,Backbone将在您的新模型中执行defaults
的浅层副本。因此,如果您m1 = new mainmodel()
和m2 = new mainmodel()
,那么m1
和m2
将具有完全相同的v4
属性。您可以使用defaults
:
var mainmodel = Backbone.Model.extend({
defaults: function() {
return {
v1: '',
v2: '',
v3: '',
v4: new collection()
};
}
});