Визуализация коллекции Backbone.js - PullRequest
15 голосов
/ 01 ноября 2011

Я - Backbone.js n00b и пытаюсь обдумать это. Я знаю, как визуализировать модель, используя представление и встроенный шаблонизатор 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"}]);
});

Он разбивается на строке атрибута шаблона в представлении, но я не уверен, что именно там мне нужно искать. Должен ли я отображать коллекцию или я здесь полностью упускаю смысл (возможно, коллекции - это просто группирующие объекты, и я не должен смотреть на это как на список, который я могу представить)?

Спасибо за помощь ...

Ответы [ 2 ]

32 голосов
/ 01 ноября 2011

Проблема в том, что при определении 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});
});
6 голосов
/ 21 мая 2013

Стоит также отметить, что существуют дополнительные сложности, которые быстро поднимают головы при рендеринге коллекции в виде. Например, представление обычно необходимо повторно визуализировать, когда модели добавляются или удаляются из коллекции. Реализовать собственное решение - не ракетостроение, но, вероятно, стоит взглянуть на существующие решения, поскольку существует немало проверенных и проверенных.

Backbone.CollectionView - это надежный класс представления коллекции, который обрабатывает выбор моделей в ответ на щелчки мыши, переупорядочивает коллекцию на основе перетаскивания, фильтрует видимые модели и т. Д.

Несколько популярных фреймворков, построенных поверх магистрали, также предоставляют простые классы представления коллекций, такие как Backbone.Marionette , Chaplin и Layout Manager .

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

...