我有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结构会是一个好主意吗?任何想法?
答案 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.save
。 Accounts
集合应覆盖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扩展程序。我通常更喜欢自定义实现的更精细控制。