Backbone.js - коллекции и виды
Я понимаю, как собрать коллекцию или отдельную модель. И обычно я могу получить данные модели для отображения. Но я не совсем понимаю, как взять коллекцию и получить список моделей в этой коллекции для отображения.
Я должен перебирать коллекцию и отображать каждую модель отдельно?
Предполагается, что это часть функции рендеринга коллекции?
Или коллекция просто имеет собственный вид и каким-то образом я заполняю все данные коллекции в виде?
Как правило, что такое обычный метод для отображения списка моделей?
Ответы
Ответ 1
По моему опыту, лучше всего хранить в своей коллекции ссылки на каждое представление модели.
Этот фрагмент проекта, над которым я сейчас работаю, должен помочь вам лучше понять:
var MyElementsViewClass = Backbone.View.extend({
tagName: 'table',
events: {
// only whole collection events (like table sorting)
// each child view has it own events
},
initialize: function() {
this._MyElementViews = {}; // view chache for further reuse
_(this).bindAll('add');
this.collection.bind('add', this.add);
},
render: function() {
// some collection rendering related stuff
// like appending <table> or <ul> elements
return this;
},
add: function(m) {
var MyElementView = new MyElementViewClass({
model: m
});
// cache the view
this._MyElementViews[m.get('id')] = MyElementView;
// single model rendering
// like appending <tr> or <li> elements
MyElementView.render();
}
});
Используя этот подход, вы можете более эффективно обновлять представления (повторное рендеринг одной строки в таблице вместо всей таблицы).
Ответ 2
Я думаю, что есть два способа сделать это.
- Используйте представление для каждого элемента и непосредственно манипулируйте DOM. Это то, что делает пример Todos. Это хороший способ сделать что-то, потому что обработка событий для одного элемента модели понятна. Вы также можете сделать один шаблон для каждого элемента. С другой стороны, у вас нет единого шаблона для представления коллекции в целом.
- Использовать представление для всей коллекции. Главное преимущество заключается в том, что вы можете делать больше манипуляций в своих шаблонах. Недостатком является то, что у вас нет шаблона для каждого элемента, поэтому, если у вас есть гетерогенная коллекция, вам нужно включить код шаблона просмотра коллекции - bletcherous.
Для второй стратегии я сделал код, который работает примерно так:
var Goose = Backbone.Model.extend({ });
var Gaggle = Backbone.Collection.extend({
model: Goose;
};
var GaggleView = Backbone.View.extend({
el: $('#gaggle'),
template: _.template($('#gaggle-template').html()),
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
}
};
var g = new Gaggle({id: 69);
g.fetch({success: function(g, response) {
gv = new GaggleView({model: g});
gv.render();
}});
Код шаблона будет выглядеть примерно так:
<script type="text/template" id="gaggle-template">
<ul id="gaggle-list">
<% _.each(gaggle, function(goose) { %>
<li><%- goose.name %></li>
<% }); %>
</ul>
</script>
Обратите внимание, что я использую _ функции (полезно!) в шаблоне. Я также использую элемент "obj", который фиксируется в функции шаблона. Вероятно, это немного обманывает; переход в {gaggle: [...]} может быть приятнее и меньше зависит от реализации.
Я думаю, когда дело доходит до него, ответ: "Есть два способа сделать это, и ни один из них не велик".
Ответ 3
Идея магистральной системы состоит в том, что рендеринг представления управляется событиями.
Представления присоединяются к событиям изменения данных модели, так что когда любые данные в модели меняют само обновление для вас.
То, что вы собираетесь делать с коллекциями, одновременно управляет набором моделей.
Я бы рекомендовал прочитать аннотированный пример.
Ответ 4
Я также нашел эту запутанную часть структуры Backbone.
Пример кода Todos - пример. Он использует 4 класса:
- Todo (расширяет Backbone.Model). Это означает, что один элемент должен быть помечен.
- TodoList (расширяет Backbone.Collection). Свойством "model" является класс Todo.
- TodoView (расширяет Backbone.View). Его tagName - "li". Он использует шаблон для рендеринга одного Todo.
- AppView (расширяет Backbone.View). Его элементом является "#todoapp". Вместо того, чтобы иметь свойство "model", он использует глобальный TodoList с именем "Todos" (непонятно, почему...). Он связывается с важными событиями изменения в Todos, а когда происходит изменение, он либо добавляет один TodoView, либо проходит через все экземпляры Todo, добавляя один TodoView за раз. У него нет единого шаблона для рендеринга; он позволяет каждому объекту TodoView отображать себя, и он имеет отдельный шаблон для рендеринга области статистики.
Это не лучший мировой пример для первого обзора. В частности, он не использует класс Router для маршрутизации URL-адресов и не отображает классы модели для ресурсов REST.
Но похоже, что "лучшей практикой" может быть просмотр каждого члена коллекции и непосредственное управление элементами DOM, создаваемыми этими представлениями.