Backbone.js: рендеринг коллекций в приложениях реального мира
Удивительно, но большинство примеров учебных приложений backbone.js предполагают чистую шиферную шифер. I-.e. что коллекции моделей сначала пустые, пока пользователь не добавит элемент. Конечно, это не так в приложении реального мира, где у вас обычно есть существующая коллекция, чтобы начать с хранилища на задней панели.
Я хотел бы знать, как люди занимаются существующими коллекциями в позвоночнике. В частности:
-
Как вы делаете сборку после того, как она была fetch
ed? Это всего лишь случай повторения в коллекции? Должно ли это быть вызвано каким-либо событием?
-
В базовых документах говорится о "начальной загрузке", что, как я понимаю, означает использование данных, доступных для начальной загрузки (это также имеет смысл с точки зрения SEO). Но как это работает на практике? Данные сбрасываются в JS на стороне сервера? Или JS проверяет DOM?
Мне кажется, что это плохой вопрос, но я надеюсь расширить его на основе ответов.
ИЗМЕНИТЬ
Таким образом, кажется, что консенсусом является добавление данных в качестве стороны JS и процесс, который при загрузке страницы.
Один большой недостаток, который я вижу в этой технике, заключается в том, что информация недоступна для пауков поисковых систем. С этой точки зрения было бы лучше извлечь его из DOM (хотя я не видел, чтобы кто-то так делал). Или, может быть, добавить сервер HTML и вставить данные в JS?
Ответы
Ответ 1
Я столкнулся с той же ситуацией, что и вы, я не всегда хочу, чтобы мои данные сначала загружались (особенно если это было из стороннего вызова api). Я не сталкивался с любыми учебниками, которые делают это, но просматривая документацию, на самом деле довольно легко. Вам просто нужно связать событие reset (оно запускается, когда вся коллекция повторно заселена) в вашей коллекции и рендеринге. Вот краткий пример:
my_application.js
window.MyApplication = {
Models: {},
Collections: {},
Views: {},
Routers: {},
init: function() {
// Start the data loading
this.someItems = new MyApplication.Collections.Items();
this.someItems.fetch();
// Start rendering the UI before the data is ready
new MyApplication.Routers.Items(this.someItems);
Backbone.history.start();
}
};
<сильные > маршрутизаторы /items _router.js
MyApplication.Routers.Items = Backbone.Router.extend({
routes: {
"" : "index"
},
initialize: function(collection) {
this.collection = collection;
},
index: function() {
var view = new MyApplication.Views.ItemsIndex({ collection: this.collection });
$('.items').html(view.render().el);
}
});
просмотр/элементы/items_index.js
MyApplication.Views.ItemsIndex = Backbone.View.extend({
initialize: function() {
_.bindAll(this, "render");
// Once the collection is fetched re-render the view
this.collection.bind("reset", this.render);
},
render: function() {
console.log(this.collection.length);
// Render content
return this;
}
});
Ответ 2
Что касается рендеринга коллекций, да, я обычно перебираю коллекцию и создаю дочерний вид для каждой из моделей. Вот ссылка, которая может быть полезна для этого http://liquidmedia.ca/blog/2011/02/backbone-js-part-3/
Когда вы его визуализируете? Хорошо, что трудно ответить, но я бы не сказал этого в ответ на какое-либо конкретное событие. Одна вещь, которая мне нравится, состоит в том, что у нас есть одно основное представление, которое отображает суб-представления, которые отображают другие под-представления. В качестве соглашения мы не передаем непосредственно DOM, но после того, как будут показаны все под-представления, мы добавим основной вид в DOM, и вся страница появится сразу. Это позволяет избежать "вспышки незакрепленного содержимого"
Что касается начальной загрузки, я вижу из содержания, что вы читаете FAQ, и это то, что я сделал на практике. Я использую ASP.Net MVC 3, поэтому у моего представления на стороне сервера будет что-то вроде (хотя я бы не поместил "книги" в глобальное пространство имен):
<script type="text/javascript">
books = new BooksCollection();
books.reset(@Html.ToJson(Model));
</script>
Надеюсь, что это поможет.
Ответ 3
На самом деле, я немного поработал над Backbone, и я обнаружил, что данные Bootstrapping действительно полезны в некоторых случаях, когда вы знаете, что вам потребуются данные AS SOON при загрузке страницы (таким образом, уменьшая дополнительный вызов AJAX)
В Symfony я делаю это, создавая необходимые данные следующим образом:
<script type="text/template" id="__user-boostrap">
{% echo your data from php or render a controller in symfony or whatever server side script/framework you want %}
// for example in symfony2, I do:
{% render "myBundle:Core:getUser" %}
</script>
Теперь, в функции initialize(), вы можете снять эти данные непосредственно из DOM и начать выполнять обычную работу:
Например, в моем маршрутизаторе я делаю
myApp.Router = Backbone.Router.extend({
var data = JSON.parse($('__user-bootstrap').html());
var __games = new myApp.Games();
__games.reset(__games.parse(data.games));
var gameList = new myApp.GameListView({ collection: __games });
$(this.gameView).html(gameList.$el);
});
Надеюсь, что это поможет...