从单个大JSON文件中获取Backbone多个集合

jac*_*101 12 json backbone.js

我想知道是否有更好的方法来创建从单个大JSON文件中获取多个集合.我有一个看起来像这样的JSON文件.

{
  "Languages": [...],
  "ProductTypes": [...],
  "Menus": [...],
  "Submenus": [...],
  "SampleOne": [...],
  "SampleTwo": [...],
  "SampleMore": [...]
}
Run Code Online (Sandbox Code Playgroud)

我正在使用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();
Run Code Online (Sandbox Code Playgroud)

对此更好的解决方案?

Pet*_*ons 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();
Run Code Online (Sandbox Code Playgroud)

一旦调用fetch()并完成了asyn回调,就可以执行诸如collections.Menus.at(0)获取已加载模型实例之类的操作.


nra*_*itz 14

您当前的方法除了很长时间外,还有多次检索大文件的风险(浏览器缓存在这里并不总是有效,特别是如果第一个请求在您创建下一个请求时尚未完成).

我认为这里最简单的选择是使用直接jQuery而不是Backbone,然后.reset()在你的集合中使用:

$.get('data/sample.json', function(data) {
    Languages.reset(data['Languages']);
    ProductTypes.reset(data['ProductTypes']);
    // etc
});
Run Code Online (Sandbox Code Playgroud)

如果你想减少冗余代码,你可以将你的集合放入类似命名空间app,然后做这样的事情(虽然它可能有点太聪明,不易清晰):

app.Languages = new LanguageCollection();
// etc

$.get('data/sample.json', function(data) {
    _(['Languages', 'ProductTypes', ... ]).each(function(collection) {
        app[collection].reset(data[collection]);
    })
});
Run Code Online (Sandbox Code Playgroud)


fgu*_*len 6

我想你可以解决你的需求,仍然留到骨干网的模式,我觉得适合我的一个优雅的解决方案是创建一个Modelfetch大的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();
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式访问所有馆藏:

myApp.languages
myApp.productTypes
...
Run Code Online (Sandbox Code Playgroud)