我有两个模型和一个系列.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()
    }
});

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.

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.

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

更新: 我突然想到,我可以覆盖解析函数并将其设置为这样……我现在有这个了:

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

推荐答案

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()返回的值都是passed to set().

不返回任何内容(类似于返回undefined)与调用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很有趣-它使处理嵌套在模型中的集合/模型变得容易得多.

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

Json相关问答推荐

Azure Data Factory JSON输出格式问题

JSON API返回多个数组,需要帮助拼合数据以存储在SQL Server数据库表中

419(未知状态)使用laravel处理PUT请求

导致此 Kotlin Retrofit2 错误的可能原因有哪些?

在 python 中循环 JSON 数组

将 json 转换为 jsonb 安全吗?

从 oracle 数据库中的 json blob 打印值

如何使用 serde_json 构建有状态的流式解析器?

JSON 字段的多个名称

jq:来自嵌套 JSON 的映射

提交后使用 Rails 7 结合 JSON 标签进行标记

如何将从嵌套 Select 返回的空值转换为空数组?

TSQL FOR JSON 嵌套值

如何在 Go 中生成带有排序键的 JSON?

可以通过 POST 使用 EventSource 传递参数的服务器发送事件 (SSE)

苗条的 JSON 输出

使用 jq,将对象数组转换为具有命名键的对象

将 JSON 对象推送到 localStorage 中的数组

如何将有向无环图 (DAG) 存储为 JSON?

[__NSCFNumber 长度]:发送到实例 UITableView 的无法识别的 Select 器