Рендеринг коллекции Backbone.js
Я - Backbone.js n00b и пытаюсь обнять его. Я знаю, как визуализировать модель с использованием представления и встроенного шаблона templates для underscore.js. Теперь я пытаюсь сделать коллекцию и то, где я застрял. Здесь нет сервера, поэтому я ничего не делаю удаленно, просто простая HTML-страница с некоторым JavaScript.
ContinentModel = Backbone.Model.extend({});
ContinentsCollection = Backbone.Collection.extend({
model: ContinentModel,
initialize: function () {
this.continentsView = new ContinentsView;
this.bind("reset", this.continentsView.render);
}
});
ContinentsView = Backbone.View.extend({
el: '#continents',
template: _.template($('#continents-template').html()),
render: function() {
var renderedContent = this.template(this.collection.toJSON());
$(this.el).html(renderedContent);
return this;
}
});
$(function() {
var continentsCollection = new ContinentsCollection();
continentsCollection.reset([{name: "Asia"}, {name: "Africa"}]);
});
Он разбивается на строку атрибута шаблона в представлении, но я не уверен, что там, где мне нужно посмотреть. Могу ли я представить коллекцию или я полностью упустил точку здесь (возможно, коллекции просто группируют объекты, и я не должен рассматривать ее как список, который я могу отобразить)?
Спасибо за помощь...
Ответы
Ответ 1
Проблема заключается в том, что при определении ContinentsView шаблон оценивается и использует $('#continents-template')
- но DOM еще не готов, поэтому он не находит шаблон.
Чтобы решить эту проблему, просто переместите назначение шаблона в функцию инициализации:
ContinentsView = Backbone.View.extend({
el: '#continents',
initialize: function() {
this.template = _.template($('#continents-template').html());
}
...
Что касается коллекций, да, они группируют объекты, в частности, наборы моделей.
Вы должны сделать код, чтобы модели (и коллекции) НЕ знали о представлениях, но только представления о моделях.
ContinentModel = Backbone.Model.extend({});
ContinentsCollection = Backbone.Collection.extend({
model: ContinentModel,
// no reference to any view here
});
ContinentsView = Backbone.View.extend({
el: '#continents',
initialize: function() {
this.template = _.template($('#continents-template').html());
// in the view, listen for events on the model / collection
this.collection.bind("reset", this.render, this);
},
render: function() {
var renderedContent = this.template(this.collection.toJSON());
$(this.el).html(renderedContent);
return this;
}
});
$(function() {
var continentsCollection = new ContinentsCollection();
continentsCollection.reset([{name: "Asia"}, {name: "Africa"}]);
// initialize the view and pass the collection
var continentsView = new ContinentsView({collection: continentsCollection});
});
Ответ 2
Также стоит отметить, что есть дополнительные сложности, которые быстро поднимают голову при рендеринге коллекции в представлении. Например, представление, как правило, должно быть повторно отображено, когда модели добавляются или удаляются из коллекции. Это не наука о ракетах, чтобы реализовать свое собственное решение, но, вероятно, стоит посмотреть на существующие решения, так как есть немало проверенных и проверенных там.
Backbone.CollectionView - это класс надежного класса коллекций, который обрабатывает выбор моделей в ответ на щелчки мыши, переупорядочивая коллекцию на основе перетаскивания, фильтрация видимых моделей и т.д.
Несколько популярных фреймворков, построенных поверх базовой линии, также предоставляют простые классы просмотра коллекции, такие как Backbone.Marionette, Chaplin и Менеджер макетов.
Несмотря на то, что сама Backbone не предоставляет никакой структуры для рендеринга коллекции, это нетривиальная проблема, и у многих людей есть разные мнения о как это должно быть сделайте. К счастью, такая общая потребность в том, что в экосистеме уже есть немало хороших вариантов.