Подтвердить что ты не робот

Backbone.js - коллекции и виды

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

Я должен перебирать коллекцию и отображать каждую модель отдельно? Предполагается, что это часть функции рендеринга коллекции?

Или коллекция просто имеет собственный вид и каким-то образом я заполняю все данные коллекции в виде?

Как правило, что такое обычный метод для отображения списка моделей?

4b9b3361

Ответ 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, создаваемыми этими представлениями.