使用复杂的JSON创建Backbone.js模型

时间:2014-12-18 11:50:48

标签: backbone.js marionette backbone-collections

我有JSON响应如下

{
    "results": [
        {
            "name": "FOO",
            "containerName": "Foo",
            "accounts": [
                {
                    "id": "10445570_7601",
                    "shareeAccountInfo": "",
                    "siteAccountId": "271555",
                    "siteId": "271555",
                    "refreshMode": "NORMAL",
                    "isNetIncl": "true",
                    "propertyId": null,
                    "amount": [
                        "0.0",
                        "USD"
                    ]
                },
                {
                    "id": "1070_20537601",
                    "shareeAccountInfo": "",
                    "siteAccountId": "271555",
                    "siteId": "271555",
                    "refreshMode": "NORMAL",
                    "isNetIncl": "true",
                    "propertyId": null,
                    "amount": [
                        "0.0",
                        "USD"
                    ]
                }
            ]
        },
        {
            "name": "FOO123",
            "containerName": "Foo123",
            "accounts": [
                {
                    "id": "10445570_20601",
                    "shareeAccountInfo": "",
                    "siteAccountId": "271555",
                    "siteId": "271555",
                    "refreshMode": "NORMAL",
                    "isNetIncl": "true",
                    "propertyId": null,
                    "amount": [
                        "0.0",
                        "USD"
                    ]
                },
                {
                    "id": "10445570_37601",
                    "shareeAccountInfo": "",
                    "siteAccountId": "271555",
                    "siteId": "271555",
                    "refreshMode": "NORMAL",
                    "isNetIncl": "true",
                    "propertyId": null,
                    "amount": [
                        "0.0",
                        "USD"
                    ]
                }
            ]
        },
        {
            "name": "FOO83838",
            "containerName": "Foo3232",
            "accounts": [
                {
                    "id": "1601",
                    "shareeAccountInfo": "",
                    "siteAccountId": "271555",
                    "siteId": "271555",
                    "refreshMode": "NORMAL",
                    "isNetIncl": "true",
                    "propertyId": null,
                    "amount": [
                        "0.0",
                        "USD"
                    ]
                }
            ]
        }
    ]
}

我遇到了从此JSON响应创建Backbone模型的问题。 我应该使用嵌套模型吗?我应该如何根据我的模型创建一个集合?相反,展平这个JSON结构会是一个好主意吗?任何想法?

1 个答案:

答案 0 :(得分:5)

您的数据结构自然适合模型集合(我将调用模型Group),其中每个Group包含Account模型的集合。此集合(以及可选的模型)应该具有对父Group的引用。

var Account = Backbone.Model.extend({

})

var Accounts = Backbone.Collection.extend({
  model: Account, 
  initialize: function(models, options) {
    this.parent = options.parent;
  }
});

var Group = Backbone.Model.extend({
  initialize: function() {
    this.accounts = new Accounts([], { parent: this });
  }
});

var Groups = Backbone.Collection.extend({
  model: Group,

  // Assuming you make requests to `/group` to produce your result JSON
  url: 'group',

  // Construct models from the `results` attribute of the response
  parse: function(response) {
    return response.results;
  }
});

有两个主要的实施选择:

持久性

如果可以从父容器中单独保留单个帐户,可能使用/group/FOO83838/account/1601之类的端点,Acccount模型可以使用默认的Backbone.Model.saveAccounts集合应覆盖url以引用父网址:

Accounts = Backbone.Collection.extend({
  // code from earlier

  url: function() {
    return this.parent.url() + '/account';
  }
});

如果帐户只能保存为整体Group模型的一部分,则需要做两件事:

首先,覆盖Account.save以委托父{q} save方法:

Account = Backbone.Model.extend({
  // code from earlier

  save: function() {
    this.collection.parent.save();
  }
});

其次,覆盖Group.toJSON以包含子帐户:

Group = Backbone.Model.extend({
  // code from earlier

  toJSON: function() {
    var json = Backbone.Model.prototype.toJSON.call(this);
    json.accounts = this.accounts.toJSON();
    return json;
  }
});

(在此示例中,我使用了集合的parent引用。如果您愿意,还可以在此模型上保存对父级的引用。)

活动

您可以允许应用代码直接收听Group.accounts事件,在这种情况下,不需要更改代码:

// Example view code
this.listenTo(group.accounts, 'change', this.onAccountChange, this);

或者,如果您更喜欢额外的封装,则可以转发子模型更改:

Group = Backbone.Model.extend({
  // code from earlier

  initialize: function() {
    this.accounts = new Accounts([], { parent: this });
    this.listenTo(this.accounts, 'all', this.onChildEvent, this);
  }

  onChildEvent: function(eventName, model, options) {
    // write logic to whitelist the events and parameters you are interested in
    this.trigger('child:' + eventName, model, options); 
  }
});


// Example view code 
this.listenTo(group, 'child:change', this.onAccountChange, this);

您还可以查看DeepModel(不再维护)或Relational等Backbone扩展程序。我通常更喜欢自定义实现的更精细控制。