backbone.js - коллекции и представления - PullRequest
13 голосов
/ 13 апреля 2011

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

Должен ли я перебирать коллекцию и визуализировать каждую модель отдельно? Это должно быть частью функции рендеринга коллекции?

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

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

Ответы [ 4 ]

13 голосов
/ 14 апреля 2011

По моему опыту, лучше всего сохранять в своей коллекции вид ссылок на вид каждой модели.

Этот фрагмент из проекта, над которым я сейчас работаю, должен помочь вам лучше понять эту идею:

var MyElementsViewClass = Backbone.View.extend({
    tagName: 'table',

    events: {
        // only whole collection events (like table sorting)
        // each child view has it's 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(); 
    }
});

Использование этого подхода позволяет более эффективно обновлять представления (повторно отображать одну строкув таблице вместо всей таблицы).

8 голосов
/ 08 января 2012

Я думаю, что есть два способа сделать это.

  • Используйте представление для каждого элемента и управляйте 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 голосов
/ 13 апреля 2011

Идея магистрали состоит в том, что рендеринг вида основан на событиях.

Представления присоединяются к событиям изменения данных модели, поэтому при изменении данных в модели представление обновляется автоматически.

Что вы должны делать с коллекциями, так это манипулировать коллекцией моделей одновременно.

Я бы рекомендовал прочитать аннотированный пример .

0 голосов
/ 08 января 2012

Я также нашел это запутанной частью основы Backbone.

Пример кода Todos является примером здесь. Он использует 4 класса:

  • Todo (расширяет Backbone.Model). Это представляет собой один элемент, который необходимо сделать.
  • TodoList (расширяет Backbone.Collection). Его «модельное» свойство - класс Todo.
  • TodoView (расширяет Backbone.View). Его tagName является "li". Он использует шаблон для визуализации одного Todo.
  • AppView (расширяет Backbone.View). Его элементом является "#todoapp". Вместо того, чтобы иметь свойство "модель", он использует глобальный список TodoList с именем "Todos" (непонятно, почему ...). Он связывается с важными событиями изменений в Todos, и, когда есть изменения, он либо добавляет один TodoView, либо перебирает все экземпляры Todo, добавляя один TodoView за один раз. У него нет ни одного шаблона для рендеринга; он позволяет каждому TodoView отображать сам, и имеет отдельный шаблон для отображения области статистики.

Это не самый лучший в мире пример для первого обзора. В частности, он не использует класс Router для маршрутизации URL-адресов и не сопоставляет классы модели с ресурсами REST.

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

...