Магистральные множественные коллекции извлекаются из одного большого файла 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();
Лучшее решение для этого?
Ответы
Ответ 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/..., который я с удовольствием расскажу, если потребуется.