Подтвердить что ты не робот

Магистральные множественные коллекции извлекаются из одного большого файла JSON

Я хотел бы знать, есть ли лучший способ создать несколько коллекций, получаемых из одного большого файла JSON. Я получил файл JSON, который выглядит так.

{
  "Languages": [...],
  "ProductTypes": [...],
  "Menus": [...],
  "Submenus": [...],
  "SampleOne": [...],
  "SampleTwo": [...],
  "SampleMore": [...]
}

Я использую url/fetch для создания каждой коллекции для каждого node 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();

Лучшее решение для этого?

4b9b3361

Ответ 1

Магистраль отлично подходит, когда ваше приложение подходит к форме, которую она предоставляет. Но не бойтесь обойти это, когда это имеет смысл для вашего приложения. Это очень маленькая библиотека. Выполнение повторяющихся и повторяющихся запросов 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 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), чтобы получить загруженные экземпляры модели.

Ответ 2

Ваш текущий подход, в дополнение к довольно длинному, рискует получить большой файл несколько раз (кеширование браузера не всегда будет работать здесь, особенно если первый запрос не был завершен к тому времени, когда вы сделаете следующий).

Я думаю, что самый простой вариант - пойти с прямым 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]);
    })
});

Ответ 3

Я думаю, что вы можете решить свою потребность и еще остаться в парадигме Backbone, я думаю, что элегантное решение, которое мне подходит, создает Model, который fetch большой 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
...

Ответ 4

Вы можете легко сделать это с помощью метода анализа. Настройте модель и создайте атрибут для каждой коллекции. Там ничего не говорит, что ваш атрибут модели должен быть единственным фрагментом данных и не может быть коллекцией.

Когда вы запустите свой выбор, он вернет весь ответ методу синтаксического анализа, который вы можете переопределить, создав в своей модели функцию синтаксического анализа. Что-то вроде:

parse: function(response) {
    var myResponse = {};
    _.each(response.data, function(value, key) {
        myResponse[key] = new Backbone.Collection(value);
    }

    return myResponse;
}

Вы также можете создавать новые коллекции на глобальном уровне или в каком-либо другом пространстве имен, если вы предпочитаете не иметь их в модели, но это зависит от вас.

Чтобы получить их от модели позже, вам просто нужно сделать что-то вроде:

model.get('Languages');

Ответ 5

backbone-relational предоставляет решение внутри магистрали (без использования jQuery.getJSON), что может иметь смысл, если вы уже используете его. Короткий ответ на fooobar.com/info/437031/..., который я с удовольствием расскажу, если потребуется.