Основа: действительно ли представления являются контроллерами? - PullRequest
26 голосов
/ 15 ноября 2011

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

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

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

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

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

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

Ответы [ 5 ]

22 голосов
/ 15 ноября 2011

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

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

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

10 голосов
/ 04 января 2012

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

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

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

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

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

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

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

8 голосов
/ 09 ноября 2013

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

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

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

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

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

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

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

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

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

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

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

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

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

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

5 голосов
/ 23 января 2013

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

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

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

Итак, магистраль не принимает это решение за вас.

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

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

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

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

Представление может иметь подпредставления, и в этом случае подпредставление взаимодействует только с родительским представлением или напрямую сконтроллер.

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

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

3 голосов
/ 13 декабря 2012

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...