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

Понимание внутренних структурных зависимостей MVC в Backbone.js

Я немного смущен w.r.t. структурные зависимости при проектировании MVC - поэтому у нас есть модель, коллекция и представление (я пока не использую контроллеры, но вопрос относится и к этому вопросу). Теперь у кого есть ссылка, с кем говорить в терминах ОО. Таким образом, коллекция представляет собой список моделей, поэтому мы можем думать об этом как от одной до многих зависимостей от коллекции к модели. В некоторых примерах кода я иногда вижу некоторую ссылку на представление в объекте "model" и ссылку модели в представлении. Иногда коллекция в представлении.

В модели я иногда вижу a this.view, и в представлении я вижу что-то вроде this.model.view или this.model и, таким образом, путаница, чтобы уточнить:)

Итак, что такое "правильный" набор зависимостей (если есть "правильный" ) или каждый может быть зависим от всех (не думайте, что это правильно) То есть, кто в идеале должен быть зависим от кого в дизайне объектов MVC на основе магистрали? Это немного запутывает, чтобы знать, как они должны быть структурно связаны, когда я вижу такие разрозненные примеры - с точки зрения noob:) Как noob, что является "правильным" способом начать структурирование моих зависимостей - как только я встану я бы, наверное, сам это понял, но для начала, как это сделать? UML-подобная диаграмма будет дополнительным бонусом;)

Другой вопрос: Иногда я вижу два вида в одном и том же фрагменте кода: например: знаменитый todo.js http://documentcloud.github.com/backbone/docs/todos.html

Теперь, хотя я понимаю потребность в нескольких взглядах, что путает, как они отличаются? Я имею в виду разницу между "el" и "tagName" и как поведение выглядит по-другому, если один из них отсутствует? Я имею в виду, что в ссылке выше одного представления используется "tagName" и другое "el", и я не совсем уверен, как они коррелируют (если вообще).

Я интенсивно просматривал документацию, но, как я уже сказал, я все еще участвую, поэтому я могу просто не понимать ее частично даже со всеми имеющимися ресурсами и может потребоваться вмешательство человека:)

4b9b3361

Ответ 1

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

представления

Представления в Backbone привязаны к определенным элементам DOM (для чего принадлежит свойство el).

Если, когда представление инициализировано, оно имеет атрибут el, а Backbone.js делает его свойством нового экземпляра представления. В противном случае он ищет атрибуты tagName, id и className, создает соответствующий объект DOM и в любом случае присваивает его свойству el для нового экземпляра представления. (Это объясняется в источнике.) Если даже нет tagName, то элемент <div> создается по умолчанию.

Итак, вы можете догадаться, почему TodoView и AppView используют разные подходы. Элемент #todoapp существует первоначально на странице в HTML, поэтому AppView может просто использовать его. Но когда создается представление для элемента todo, для него еще нет элемента DOM; поэтому разработчик имеет tagName, определенный в классе для Backbone, чтобы автоматически создать элемент списка. (Нетрудно сделать вручную метод initialize(), но Backbone экономит время, выполняя его для вас.)

Обычно представление относится к одной из двух категорий: представления для экземпляров модели и представления для коллекций. Магистраль не форсирует его, но предполагает, что он, вероятно, вам нужен: если вы создаете представление с параметрами collection или model, они становятся свойствами вновь созданного экземпляра представления, поэтому вы можете получить к ним доступ через view.collection или view.model. (Если вы, например, создаете экземпляр представления с опцией foo, он будет помещен в view.options.foo.)

Зависимости

Передовая практика

Это только мое мнение.

  • Меньшая зависимость лучше.

  • После шаблона MVC есть много преимуществ.

    Обратите внимание, что терминология Backbone.js не соответствует классической MVC. Этот нормальный MVC!= Набор классов, и его определения немного отличаются. Это больше "идеал, который вы должны иметь в своем воображении" (цитируется Что такое MVC и каковы его преимущества?).

MVC        | Backbone.js                 | What it does
Controller | View (mostly)               | Handles user interaction
View       | template rendered by a view | Displays the data
Model      | Model & Collection          | Represents the data, handles data access
  • Слой модели обычно не должен зависеть от чего-либо. В MVC модель - это то, где вы получаете доступ к своим данным. Это не имеет никакого отношения, например, к представлению этих данных.

    В Backbone модель может быть частью некоторой коллекции, но это не тяжелая зависимость (AFAIK, она просто помогает автоматически определять URL-адреса конечных точек API, соответствующих этой модели.)

  • В Backbone в коллекции может быть назначен соответствующий класс модели, но это также необязательно.

  • В Backbone маршрутизатор обычно зависит от представлений более высокого уровня (например, просмотров для целых страниц или разделов страницы), чтобы отображать их в ответ на изменение состояния приложения. Эти взгляды, в свою очередь, зависят от некоторых представлений более низкого уровня, таких как виджеты/разделы страниц. Эти взгляды могут зависеть от коллекций и других, даже более низкоуровневых представлений. Это, в свою очередь, может зависеть от конкретных экземпляров модели.

В качестве примера (стрелки обозначают "зависит от" типа отношения):

           +-------------+              +---------------+   +------------+
State      |MainRouter   |       Data:  |ItemCollection |   |ItemModel   |
Control:   |-------------|              |---------------|   |------------|
           |             |              |/api/items     +-->|/api/items/*|
           |             |              |               |   |            |
           |             |              |               |   |            |
           +---+-+-------+              +---------------+   +------------+
               | +----------------+                  ^              ^
               v                  v                  |              |
           +-------------+   +-------------+         |              |
Page-level |AboutView    |   |AppView      |         |              |
views:     |-------------|   |-------------|         |              |
           | section     |   | section     |         |              |
           | role="main" |   | role="main" |         |              |
           +--+-+--------+   +--+-+-+------+         |              |
              | +---------------|-|-|----+           |              |
              |      +----------+ | +----|---------+ |              |
              v      v            v      v         v |              |
           +--------------+   +--------------+   +---+-----------+  |
Widget     |SidebarView   |   |HeaderView    |   |ItemListView   |  |
views:     |--------------|   |--------------|   |---------------|  |
           | aside        |   | header       |   | ul            |  |
           |              |   |              |   |               |  |
           |              |   |              |   |               |  |
           +--------------+   +--------------+   +-----------+---+  |
                                                             |      |
                                                             v      |
                                                           +--------+---+
                                                           |ItemAsLiView|
                                                           |------------|
                                                           | li         |
                                                           |            |
                                                           +------------+

Обратите внимание, что вы можете настроить несколько маршрутизаторов, и в этом случае все может выглядеть несколько иначе.

todos.js

В примере Todos разработчик решил, что экземпляры модели Todo должны зависеть от соответствующих экземпляров TodoView. Когда TodoView создается, он создает в соответствующем экземпляре модели свойство view и присваивает ему. Чтобы к нему можно было получить доступ some_todo_model.view. Однако следует отметить, что model.view используется только один раз в Todo метод модели clear(), чтобы удалить экземпляр представления, когда модель очищена.

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

Я не смог найти какой-либо пример доступа к this.model.view в представлении, поэтому я не могу прокомментировать это.

См. также