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

Магистраль: действительно ли есть контроллеры?

Я создаю свое первое приложение Backbone.js, и я смущен тем, какую ответственность я должен отдать или скрыть от своих просмотров.

В моем примере я создаю таблицу Rich UI (похожую на YUI datagrid), которая динамически генерируется из коллекции. В моем приложении я называю это "AppTable". В моем понимании MVC я бы предположил, что будет какой-то контроллер AppTable, который найдет правильную коллекцию, захватит "немой" вид и перейдет к просмотру любой информации из коллекции, которую нужно отобразить. В этом senario представление будет делать немного больше, чем принимать предоставленные данные и изменять DOM соответственно, возможно, даже заполняя шаблон или добавляя прослушиватели событий.

Магистраль, похоже, покончит с идеей о том, что контролер будет посредником между View и Collection. Вместо этого View получает инициализацию со ссылкой на коллекцию, и на нее возлагается ответственность за обновление самой.

Я правильно понимаю эту архитектуру?

Предполагая, что я это делаю, тогда мой вопрос становится, что происходит, когда мой взгляд должен делать все больше и больше? Например, мне нужна сортировка столбцов, перетаскивание для строк, разбиение на страницы, поиск, ссылки управления таблицей (например, новые, копирование, удаление строки... и т.д.) И многое другое. Если мы придерживаемся "умной" парадигмы вида, где "Вид" напрямую связан с коллекцией, добавляются ли эти функции к объекту "Просмотр"?

Размышляя об этом, я мог видеть, как "Вид" растет от простой табличной оболочки до довольно беспорядочного зверя с множеством функциональных возможностей, связанных с ним. Итак, действительно ли View является контроллером в этом случае?

4b9b3361

Ответ 1

Ваше понимание архитектуры правильное. Магистраль не признает концепцию "контроллера" в традиционном смысле MVC. (На самом деле, у Backbone на самом деле был объект с именем Controller, но он был переименован в Router, чтобы более точно описать, что он делает.)

Функции, которые вы перечисляете (перетаскивание, удаление строк, сортировка и т.д.), будут принадлежать в представлении. В представлении описывается, что вы видите и реагируете на ввод пользователя. Все, что связано с событием (щелчок, нажатие клавиши, подача и т.д.), Попадают внутрь представления. Но ваше мнение никогда не должно фактически манипулировать данными; это должно быть сделано его model. Вы правы, думая, что представление действует как контроллер, потому что оно упаковывает данные и отправляет их в модель, которая затем будет правильно проверять/устанавливать/сохранять. После того, как эти действия произошли, представление повторно отображает себя для представления новой версии данных внутри модели.

Одно примечание: ваше мнение не должно быть слишком сильно привязано к DOM. Это соглашение Backbone должно иметь элемент DOM верхнего уровня, к которому привязан ваш взгляд (например, форма или div), а затем обрабатывать только его подэлементы. Это уместно; в общем, такие вещи, как "удалить эту ссылку из этого div" внутри вашего представления, нет. Если вы обнаружите, что ваш взгляд становится громоздким, вам, скорее всего, придется разбить его на подвид, каждый со своим поведением в качестве компонентов всего их.

Ответ 2

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

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

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

Обновление:. После шести месяцев создания Backbone-приложений я понял, что маршрутизаторы можно разделить и расширить, как и представления. (Дух?)

С самого начала я знал, что должен сделать базовый взгляд на функциональность, я знаю, что все мои взгляды понадобятся. Точно так же я делал бы базовые представления для каждого раздела, например, страницы "профиля" или "входящие" страницы, которые, как я знаю, будут использовать одни и те же функции. Это было не очень ясно для меня в начале с маршрутизаторами, но на это намекало предыдущее имя "Контроллер".

Большинство людей (как и в каждом примере Backbone, которое я когда-либо видел в Интернете) просто используют один монолитный экземпляр маршрутизатора для обработки всех маршрутов, но на самом деле вы можете иметь соотношение "1 к 1" маршрутизаторов для просмотров или в моем case, базовый маршрутизатор для проверки подлинности пользователя и т.д., а затем по одному для каждого основного раздела. Таким образом, если вам необходимо передать определенные модели или коллекции маршрутизатору при загрузке страницы, вам не нужно добавлять код на один монолитный маршрутизатор, но вместо этого вытащите уникальный маршрутизатор для этого представления. Я считаю, что в настоящее время это лучше, чем создание отдельного класса контроллера. Базовый маршрутизатор может отвечать за последний экземпляр представления и т.д., Поэтому вы можете убить последнее представление перед созданием нового.

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

Ответ 3

Я пытался бороться с одними и теми же семантическими проблемами при попытке сопоставить одностраничное приложение. В конце концов я решил, что Backbone использует неправильное имя.

Когда вы смотрите на приложение Backbone в браузере, представление вообще не является видом, его элемент el - это представление. Backbone.View является либо контроллером представления, либо, возможно, более корректным, презентатором.

Некоторые подтверждающие доказательства:

  • вы никогда не видите Backbone.View на экране, всегда el или $el, который применяется к DOM

  • a Backbone.View не получает пользовательский ввод, элемент DOM получает вход и события делегируются через хеш events "view"

  • a Backbone.View управляет изменениями модели или коллекции и преобразует эти изменения в элементы DOM-представления (DOM), а затем применяет их к фактическому виду, например. this.$el.append('<p>Cats!')

Я думаю, что Backbone.Presenter будет лучшим именем, но я также могу увидеть исторические проблемы с тем, что есть прежний Backbone.Controller и количество переименований работы.

Я применил следующую структуру для моего последнего проекта:

  • контроллер приложения, расширенный от Backbone.View, привязанный к элементу body

  • несколько коллекций моделей для кэширования данных, полученных с сервера

  • a Backbone.Router, который преобразует изменения маршрута в базовые события и запускает их сам по себе

  • многие методы контроллера приложения, которые обрабатывают события маршрутизатора, которые контроллер приложения прослушивает

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

Все эти части инициируются и принадлежат контроллеру приложения. Ведущие не знают, почему и где они находятся на странице, и заботятся только о своих собственных элементах DOM и изменениях, которые они получают от this.model.

Ответ 4

Посмотрите на эту часть базовой документации

http://documentcloud.github.com/backbone/#FAQ-tim-toady

Ссылки между моделями и представлениями можно обрабатывать несколькими способами. Некоторые людям нравятся прямые указатели, где представления соответствуют 1:1 с моделей (model.view и view.model). Другие предпочитают иметь промежуточные объекты "контроллера", которые организуют создание и организацию взглядов в иерархию. Другие по-прежнему предпочитают предполагаемый подход, и всегда запускайте события, а не вызывайте методы напрямую. Все эти стили работают хорошо.

Итак, позвоночник не принимает это решение для вас.

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

В моем случае я сначала начал с того, что Router вел себя так же, как контроллер, и довольно быстро мой код немного запутался.

Итак, я полностью удалил маршрутизаторы (я добавлю их позже, но как дополнение) и создаю свой собственный контроллер (который фактически работает как ведущий). Это просто класс javascript с поддержкой Backbone.extend для обработки наследования.

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

В представлении могут быть субвью, и в этом случае subview взаимодействует только с родительским представлением или напрямую с контроллером.

Пока это работает, но все равно все не так просто, как я ожидал, что они будут...

Я надеюсь опубликовать его в ближайшие несколько дней.

Ответ 5

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

Лично мой контроллер является объединением "сырых" маршрутов Javascript и Backbone, и я никогда не использую Views для логики управления вообще. Представления IMHO предназначены для... ну, логики просмотра и, в частности, для обертывания элементов. Если вы используете представление для чего-либо, что напрямую не связано с элементом HTML (опять же, IMHO), что-то не так.

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