Backbone.js模型与集合

时间:2011-08-21 19:58:54

标签: javascript ajax json backbone.js

我有2个模型和一个集合。 JobSummary是一个模型,JobSummaryListJobSummary项的集合,然后我有JobSummarySnapshot模型,其中包含JobSummaryList

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

我认为这是有道理的,因为除了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
});

更新: 在我看来,我可以覆盖解析函数并设置它......我现在有了这个:

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

到目前为止这是有效的。保留问题以防有人评论....

1 个答案:

答案 0 :(得分:56)

你的parse()函数不应该set()任何东西,只是返回属性是更好的做法,Backbone将负责设置它。 e.g。

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

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

不返回任何内容(类似于返回undefined)与调用set(undefined)相同,这可能会导致它无法通过验证,或者如果您的自定义validate()会导致其他一些意外结果/ set()方法期望获得一个对象。如果您的验证或set()方法因此失败,则不会调用传递给options.success的{​​{1}}回调。

另外,为了使其更通用,以便Backbone.Model#fetch()来自其他地方的普通对象(而不仅仅来自服务器响应)也会影响它,您可能希望覆盖set()而不是:

set()

您可能还会发现Backbone-relational很有趣 - 它可以更轻松地处理嵌套在模型中的集合/模型。

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