2011-08-21 166 views
36

我有2个模型和一个集合。 JobSummary是一个模型,JobSummaryListJobSummary项的集合,然后我有一个JobSummarySnapshot模型包含JobSummaryListBackbone.js模型与集合

JobSummary = Backbone.Model.extend({}); 

JobSummaryList = Backbone.Collection.extend({ 
    model: JobSummary 
}); 

JobSummarySnapshot = Backbone.Model.extend({ 
    url: '/JobSummaryList', 

    defaults: { 
     pageNumber: 1, 
     summaryList: new JobSummaryList() 
    } 
}); 

当我打电话fetchJobSummarySnapshot对象上,它得到的一切......除非我通过summaryList集合,他们都是类型object而不是JobSummary

我想这是有道理的,因为除了defaults对象外,它不知道summaryList应该是JobSummaryList类型。我可以通过每个项目并将其转换为JobSummary对象,但我希望有一种方法可以做到而不必手动完成。

这里是我的测试代码(工作jsfiddle here):

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: 它发生,我认为我可以覆盖的解析功能,并设置它的方式......我现在有这样的:

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}); 
    } 
}); 

此功能到目前为止。如果有人对此发表评论,请留下问题......

回答

55

您的parse()函数不应该set()任何东西,它只是返回属性的一种更好的做法,Backbone将负责设置它。例如

parse: function(response) { 
    response.summaryList = new JobSummaryList(response.summaryList); 
    return response; 
} 

无论你从parse()返回是passed to set()

不返回任何东西(这好像回到undefined)是一样的调用set(undefined),这可能导致其无法,如果您的自定义validate()/set()方法希望得到一个对象通过验证,或其他一些意想不到的结果。如果您的验证或set()方法因此而失败,则不会调用传递给Backbone.Model#fetch()options.success回调。

此外,为了使这个更通用,这样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-relational有趣 - 它使处理嵌套在模型中的集合/模型变得更容易。

编辑我忘了从set()方法返回,代码现已更新

+0

非常感谢你。我今天只读了一半的东西,再一次,它咬了我一口。它在文档中清楚地表明,正如你在上面提到的那样,你从解析函数返回obj ......但是我不知怎的错过了。再次感谢。 –

+1

爱'set'例子! – Bart