backbone.js-重写的parse()不设置模型属性
我有一个模型链接到两个子模型,如下所示:backbone.js-重写的parse()不设置模型属性,backbone.js,Backbone.js,我有一个模型链接到两个子模型,如下所示: var SubModel = Backbone.Model.extend({ defaults: { headline: null, image_url: null, url: null } }); var MainModel = Backbone.Model.extend({ defaults: { subModelA: null, subMode
var SubModel = Backbone.Model.extend({
defaults: {
headline: null,
image_url: null,
url: null
}
});
var MainModel = Backbone.Model.extend({
defaults: {
subModelA: null,
subModelB: null,
title: null
},
urlRoot: function() {
if (this.isNew()) {
return '/mainmodel/new';
}
return '/mainmodel';
},
initialize: function() {
this.fetch();
},
parse: function(data) {
var response = {};
response.subModelA = new SubModel(data.subModelA);
response.subModelB = new SubModel(data.subModelB);
response.title = data.title;
return response;
}
});
我目前遇到的问题是,调用var mainModelInstance=new MainModel()
确实可以正确地从/MainModel/new
获取,但是mainModelInstance.attributes
始终是一个空对象{}
var mainModelInstance = new MainModel();
mainModelInstance.attributes; // Returns {}
以下是服务器对/mainmodel/new
的响应示例:
{
"title": "Politics",
"subModelA": {
"headline": "Investigators: Iran tried to smuggle suicide belts, missiles by boat into Yemen",
"url": "http://dailycaller.com/2013/02/09/yemen-minister-says-weapons-came-from-iran/",
"image_url": "http://cdn01.dailycaller.com/wp-content/uploads/2013/02/54c7d52e1a384db489ab9ea568afddb0-e1360455589316.jpg"
},
"subModelB": {
"headline": "Review: Who needs Windows RT? Acer's Iconia W510 runs the real thing",
"url": "http://arstechnica.com/gadgets/2013/02/review-who-needs-windows-rt-acers-iconia-w510-runs-the-real-thing/",
"image_url": "http://cdn.arstechnica.net/wp-content/uploads/2013/02/w510-main-640x388.jpg"
}
}
似乎模型的属性没有通过
parse
更新。为什么不更新模型的属性?首先,必须将默认属性值放入defaults
选项中,如下所示:
var SubModel = Backbone.Model.extend({
defaults: {
headline: null,
image_url: null,
url: null
}
});
然后,在创建新实例时,您将有值保存到服务器。这也将填充您的mainModelInstance.attributes
hash
对于解析问题,您是否已将(
console.log
)记录在从服务器返回的内容中?这只是一个正在进行的回答,请随时在评论中讨论
我将更改您的main模型定义,如下所示:
subModelA: new SubModelA(),
subModelB: new SubModelB(),
parse: function(data){
this.subModelA.set(data.subModelA);
this.subModelB.set(data.subModelB);
return data; // we keep two copies of the data, in mainModel and submodels.
}
所以假设您的服务器响应与您的答案完全相同
var model = new MainModel();
model.get('title'); // Politics
model.subModelA.get('headline'); // Investigators: Iran tr...
然后,您可能必须重写save方法,这取决于您希望将内容持久化回服务器的方式—这可能会起作用
save: function(key, val, options) {
this.set({
subModelA: this.subModelA.toJSON(),
subModelB: this.subModelB.toJSON()
});
Backbone.Model.prototype.save.apply(this, arguments);
}
您的代码也可以正常工作,但您没有正确地测试它
您正在调用初始化方法中的this.fetch
。
调用model.fetch
是一个异步调用,当您尝试评估mainModelInstance.attributes
时,http请求调用尚未完成
您应该使用以下方法对此进行测试:
var mainModelInstance = new MainModel();
mainModelInstance.on('change', function() {
console.log(mainModelInstance.toJSON());
});
或者更好的是,不要在初始化时自动提取(无论如何这不是最佳做法)
并使用jQuery承诺模式:
var mainModelInstance = new MainModel();
mainModelInstance.fetch().done(function () {
console.log(mainModelInstance.toJSON());
});
不确定您的问题的确切答案,但有两个简要说明:请注意,像MainModel的子模型a
和子模型b
这样的模型实例属性与模型数据属性不同,因此尝试通过解析建立它们不会直接将它们设置为实例属性,而只是将它们设置到属性散列中。另外,您的代码在REST约定方面非常奇怪。您应该通过model.save、not fetch和POST not GET创建新模型。到目前为止,我想,您只需要从parse()方法返回json。不要在那里创建任何实例。@PeterLyons这不是典型的REST场景。MainModel
没有默认填充的初始状态,也没有等效的创建、更新或删除方案。此模型将有一个自定义方法,可有效记录子模型a
或子模型B
之间的选择MainModel
代表了某种“配对”。@MikeSukmanowsky也许你可以帮助我们解释一下你想要完成什么,而不是如何完成?你说的选择是什么意思?另外,@HungryCoder是正确的-parse
是进行模型实例化的错误位置。它的工作只是获取一个json对象并更新模型属性。您可以在这里看到它是如何在内部使用的:您可能只是在异步请求完成之前检查属性。尝试this.fetch({success:function(model){console.log(model.attributes);})
我有,并且响应有效是的。。我没有任何特定的内容要添加,但在这里创建了一个jsBin。你比我先得出了答案:)覆盖同步
作为演示。这是不正确的。默认属性是可选的,仅用于设置初始值。@UziKilon你是对的,我不相信我错过了这么简单的错误或者!当然,您可能会发现自己也覆盖了其他方法,如update
。因此,这就引出了一个问题,您需要多个模型吗?我肯定正在考虑删除子模型。最大的好处是分解视图模板,但这可能比它的价值更大。谢谢您的回答!我的解析实现n一直在工作,但由于fetch()
是异步的,我过早地开始期望更新model.attributes
。