我有2个模型和1个收藏集。JobSummary是一个模型,JobSummaryList是JobSummary项目的集合,然后我有一个JobSummarySnapshot模型,其中包含JobSummaryList:
JobSummary
JobSummaryList
JobSummarySnapshot
JobSummary = Backbone.Model.extend({}); JobSummaryList = Backbone.Collection.extend({ model: JobSummary }); JobSummarySnapshot = Backbone.Model.extend({ url: '/JobSummaryList', defaults: { pageNumber: 1, summaryList: new JobSummaryList() } });
当我调用fetch该JobSummarySnapshot对象时,它得到了所有东西…除了当我在summaryList集合中移动时,它们都是类型object而不是类型JobSummary。
fetch
summaryList
object
我认为这是有道理的,因为除了defaults对象之外,它不知道the summaryList的类型应该是JobSummaryList。我可以遍历每个项目并将其转换为JobSummary对象,但是我希望有一种无需手动进行操作的方法。
defaults
这是我的测试代码(在这里使用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 });
更新:我想到我可以覆盖解析函数并以这种方式设置…我现在有这个:
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}); } });
到目前为止,该方法有效。让问题开放,以防有人对此发表评论。
您的parse()函数应该set()什么也不做,只是返回属性的一种更好的做法,Backbone将负责设置它。例如
parse()
set()
parse: function(response) { response.summaryList = new JobSummaryList(response.summaryList); return response; }
无论您返回什么,parse()都会传递给set()。
不返回任何内容(就像return一样undefined)与调用相同set(undefined),这可能导致它不通过验证,或者如果您的自定义validate()/ set()方法希望获得一个对象,则可能导致其他意外结果。如果您的验证或set()方法因此而失败,则不会options.success调用传递给的回调Backbone.Model#fetch()。
undefined
set(undefined)
validate()
options.success
Backbone.Model#fetch()
另外,为了使其更通用,以便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); }
您可能还会发现Backbone关系很有趣- 它使处理嵌套在模型中的集合/模型更加容易。
编辑 我忘了从set()方法返回,代码现在已更新