我想知道是否有更好的方法来创建从单个大JSON文件中获取多个集合。我有一个JSON文件看起来像这样。
{
"Languages": [...],
"ProductTypes": [...],
"Menus": [...],
"Submenus": [...],
"SampleOne": [...],
"SampleTwo": [...],
"SampleMore": [...]
}
我正在使用url / fetch为上面JSON的每个节点创建每个集合。
var source = 'data/sample.json';
Languages.url = source;
Languages.fetch();
ProductTypes.url = source;
ProductTypes.fetch();
Menus.url = source;
Menus.fetch();
Submenus.url = source;
Submenus.fetch();
SampleOne.url = source;
SampleOne.fetch();
SampleTwo.url = source;
SampleTwo.fetch();
SampleMore.url = source;
SampleMore.fetch();
对此更好的解决方案吗?
答案 0 :(得分:18)
当您的应用程序适合其提供的模具时,Backbone非常适合。但是,当你的应用程序有意义时,不要害怕绕过它。这是一个非常小的图书馆。为了适应骨干模具而做出重复和重复的GET请求可能效率极低。查看jQuery.getJSON或您最喜欢的基本AJAX库,并配合以下基本元编程:
//Put your real collection constructors here. Just examples.
var collections = {
Languages: Backbone.Collection.extend(),
ProductTypes: Backbone.Collection.extend(),
Menus: Backbone.Collection.extend()
};
function fetch() {
$.getJSON("/url/to/your/big.json", {
success: function (response) {
for (var name in collections) {
//Grab the list of raw json objects by name out of the response
//pass it to your collection's constructor
//and store a reference to your now-populated collection instance
//in your collection lookup object
collections[name] = new collections[name](response[name]);
}
}
});
}
fetch();
调用fetch()
并完成asyn回调后,您可以执行collections.Menus.at(0)
之类的操作来获取已加载的模型实例。
答案 1 :(得分:14)
您当前的方法除了很长时间外,还有多次检索大文件的风险(浏览器缓存在这里并不总是有效,特别是如果第一个请求在您创建下一个请求时尚未完成)。
我认为这里最简单的选择是使用直接jQuery,而不是Backbone,然后在您的集合中使用.reset()
:
$.get('data/sample.json', function(data) {
Languages.reset(data['Languages']);
ProductTypes.reset(data['ProductTypes']);
// etc
});
如果你想减少冗余代码,你可以把你的集合放到像app
这样的命名空间中然后做这样的事情(虽然它可能有点太聪明而不清晰):
app.Languages = new LanguageCollection();
// etc
$.get('data/sample.json', function(data) {
_(['Languages', 'ProductTypes', ... ]).each(function(collection) {
app[collection].reset(data[collection]);
})
});
答案 2 :(得分:6)
我认为你可以解决你的需求并仍然坚持Backbone范例,我认为一个适合我的优雅解决方案是创建一个Model
fetch
< em> big JSON 并将其用于fetch
Collections
事件中的所有change
:
var App = Backbone.Model.extend({
url: "http://myserver.com/data/sample.json",
initialize: function( opts ){
this.languages = new Languages();
this.productTypes = new ProductTypes();
// ...
this.on( "change", this.fetchCollections, this );
},
fetchCollections: function(){
this.languages.reset( this.get( "Languages" ) );
this.productTypes.reset( this.get( "ProductTypes" ) );
// ...
}
});
var myApp = new App();
myApp.fetch();
您可以通过以下方式访问所有馆藏:
myApp.languages
myApp.productTypes
...
答案 3 :(得分:4)
您可以使用解析方法轻松完成此操作。设置模型并为每个集合创建属性。没有任何迹象表明您的模型属性必须是单个数据,不能是集合。
当你运行你的fetch时,它会将整个响应返回给你可以通过在模型中创建一个parse函数来覆盖的parse方法。类似的东西:
parse: function(response) {
var myResponse = {};
_.each(response.data, function(value, key) {
myResponse[key] = new Backbone.Collection(value);
}
return myResponse;
}
如果您不想将它们包含在模型中,您还可以在全局级别或其他命名空间中创建新集合,但这取决于您。
要从模型中获取它们,您只需执行以下操作:
model.get('Languages');
答案 4 :(得分:0)
backbone-relational在骨干内提供了一个解决方案(不使用jQuery.getJSON),如果你已经在使用它,这可能是有意义的。 https://stackoverflow.com/a/11095675/70987的简短回答,如果需要,我很乐意详细说明。