Backbone.js 模型与集合 [英] Backbone.js model with collection

查看:17
本文介绍了Backbone.js 模型与集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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:

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

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

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

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

当我在 JobSummarySnapshot 对象上调用 fetch 时,它获取所有内容......除了当我在 summaryList 集合中移动时,它们都是类型为 object 而不是 JobSummary.

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.

我认为这是有道理的,因为除了 defaults 对象,它不知道 summaryList 应该是 JobSummaryList 类型.我可以浏览每个项目并将其转换为 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.

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

Here's my test code (working 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
});

更新:我突然想到我可以覆盖 parse 函数并以这种方式设置它......我现在有了这个:

UPDATE: It occurred to me that I could override the parse function and set it that way... I have this now:

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....

推荐答案

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

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: function(response) {
    response.summaryList = new JobSummaryList(response.summaryList);
    return response;
}

无论你从 parse() 返回什么都是 传递给set().

Whatever you return from parse() is passed to set().

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

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.

此外,为了使这更通用,以便 set() 从其他地方(不仅是从服务器响应)到普通对象也会影响它,您可能想要覆盖 set() 代替:

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: 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 很有趣 - 它可以更轻松地处理集合/models 嵌套在模型中.

You might also find Backbone-relational interesting - it makes it much easier to deal with collections/models nested inside models.

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

edit I forgot to return from the set() method, the code is now updated

这篇关于Backbone.js 模型与集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆