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

时间:2012-03-20 03:48:21

标签: json backbone.js

我想知道是否有更好的方法来创建从单个大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();

对此更好的解决方案吗?

5 个答案:

答案 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的简短回答,如果需要,我很乐意详细说明。