Javascript Backbone.js 模型与集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7140741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Backbone.js model with collection
提问by Bryce Fischer
I have 2 models and one collection. JobSummary
is a model, JobSummaryList
is a collection of JobSummary
items, and then I have a JobSummarySnapshot
model that contains a JobSummaryList
:
我有 2 个模型和一个系列。JobSummary
是一个模型,JobSummaryList
是一个JobSummary
项目的集合,然后我有一个JobSummarySnapshot
包含以下内容的模型JobSummaryList
:
JobSummary = Backbone.Model.extend({});
JobSummaryList = Backbone.Collection.extend({
model: JobSummary
});
JobSummarySnapshot = Backbone.Model.extend({
url: '/JobSummaryList',
defaults: {
pageNumber: 1,
summaryList: new JobSummaryList()
}
});
When I call fetch
on the JobSummarySnapshot
object, it gets everything... Except when I move through the summaryList
collection they are all of type object
and not JobSummary
.
当我调用fetch
该JobSummarySnapshot
对象时,它会获取所有内容......除了当我在summaryList
集合中移动时,它们都是 typeobject
而不是JobSummary
。
I suppose this makes sense since other than the defaults
object, it doesn't know that the summaryList
should be of type JobSummaryList
. I can go through each item and convert it to a JobSummary
object, but I was hoping there was a way to do it without having to do it manually.
我想这是有道理的,因为除了defaults
对象之外,它不知道summaryList
应该是 type JobSummaryList
。我可以浏览每个项目并将其转换为JobSummary
对象,但我希望有一种方法可以做到这一点,而无需手动进行。
Here's my test code (working jsfiddle here):
这是我的测试代码(在此处使用 jsfiddle):
var returnData = {
pageNumber: 3,
summaryList: [
{
id: 5,
name: 'name1'},
{
id: 6,
name: 'name2'}
]
};
var fakeserver = sinon.fakeServer.create();
fakeserver.respondWith('GET', '/JobSummaryList', [200,
{
'Content-Type': 'application/json'},
JSON.stringify(returnData)]);
var callback = sinon.spy();
var summarySnapshot = new JobSummarySnapshot();
summarySnapshot.bind('change', callback);
summarySnapshot.fetch();
fakeserver.respond();
var theReturnedList = callback.getCall(0).args[0].attributes.summaryList;
_.each(theReturnedList, function(item) {
console.log('Original Item: ');
console.log(item instanceof JobSummary); // IS FALSE
var convertedItem = new JobSummary(item);
console.log('converted item: ');
console.log(convertedItem instanceof JobSummary); // IS TRUE
});
UPDATE: It occurred to me that I could override the parse function and set it that way... I have this now:
更新:我突然想到我可以覆盖 parse 函数并将其设置为...我现在有这个:
JobSummarySnapshot = Backbone.Model.extend({
url: '/JobSummaryList',
defaults: {
pageNumber: 1,
summaryList: new JobSummaryList()
},
parse: function(response) {
this.set({pageNumber: response.pageNumber});
var summaryList = new JobSummaryList();
summaryList.add(response.summaryList);
this.set({summaryList: summaryList});
}
});
This works so far. Leaving the question open in case someone has comment on it....
到目前为止,这有效。如果有人对此发表评论,请留下问题....
回答by shesek
Your parse()
function shouldn't set()
anything, its a better practice to just return the attributes, Backbone will take care of setting it. e.g.
你的parse()
函数不应该有set()
任何东西,只是返回属性是更好的做法,Backbone 会负责设置它。例如
parse: function(response) {
response.summaryList = new JobSummaryList(response.summaryList);
return response;
}
Whatever you return from parse()
is passed to set()
.
无论您从中返回什么,parse()
都将传递给set()
.
Not returning anything (which is like returning undefined
) is the same as calling set(undefined)
, which could cause it not to pass validation, or some other unexpected results if your custom validate()
/set()
methods expects to get an object. If your validation or set()
method fails because of that, the options.success
callback passed to Backbone.Model#fetch()
won't be called.
不返回任何内容(就像返回undefined
)与调用相同set(undefined)
,如果您的自定义validate()
/set()
方法希望获得一个对象,这可能会导致它无法通过验证,或其他一些意外结果。如果您的验证或set()
方法因此失败,则不会options.success
调用传递给的回调Backbone.Model#fetch()
。
Also, to make this more generic, so that set()
ing to a plain object from other places (and not only from the server response) also effects it, you might want to override set()
instead:
此外,为了使这更通用,以便set()
从其他地方(不仅是从服务器响应)到普通对象也会影响它,您可能想要覆盖set()
:
set: function(attributes, options) {
if (attributes.summaryList !== undefined && !(attributes.summaryList instanceof JobSummaryList)) {
attributes.summaryList = new JobSummaryList(attributes.summaryList);
}
return Backbone.Model.prototype.set.call(this, attributes, options);
}
You might also find Backbone-relationalinteresting - it makes it much easier to deal with collections/models nested inside models.
您可能还会发现Backbone-relational很有趣——它使处理嵌套在模型中的集合/模型变得更加容易。
editI forgot to return from the set() method, the code is now updated
编辑我忘记从 set() 方法返回,代码现在更新