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

Должны ли связанные обратные ссылки Backbone.js ссылаться друг на друга или говорить только через события?

У меня есть приложение, которое делает CRUD для Collection of Models. Для каждой модели всегда есть DisplayView, которая всегда видна. Существует также EditView, который отображается только при нажатии на соответствующий DisplayView.

DisplayView и EditView отображаются внутри разных родительских представлений. Прямо сейчас я использую шаблон "агрегатор событий", чтобы сообщить моему приложению о рендеринге EditView при нажатии DisplayView. Шаблон, описанный здесь: http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/

При щелчке по одному из моих DisplayView он запускает событие, которое прослушивает родительский элемент EditViews. Когда он получает это событие, он отображает соответствующий EditView на основе модели, для которой было запущено событие.

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

Проблема, как я уже сказал, заключается в том, что они отображаются внутри разных родительских представлений. DisplayViews получают в HeaderView, а EditViews получают в ContentView.

Как другие справляются с ситуациями вроде этого? EditView в некотором роде относится к DisplayView, но это не совпадает с тем, как структурировано мое приложение DOM. Предполагая, что я создаю прямую связь между каждыми EditView и DisplayView, как мне обрабатывать show/hide из EditView? Будет ли DisplayView также нужна ссылка на контейнер ContentView, который он явно отобразит с помощью соответствующего EditView в качестве параметра?

4b9b3361

Ответ 1

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

Глобальные уведомления/события

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

Шаблон привязки/наблюдателя

сделать объект с именем editViewPosition в вашем контроллере и выставить методы, чтобы представление на экране изменило значения editViewPosition. Затем EditView мог прослушивать и наблюдать изменения в editViewPosition и обновлять их соответствующим образом. Сила этого подхода заключается в том, что позже вы можете иметь 5 разных EditViews, которые будут наблюдать одно и то же свойство editViewPosition на вашем контроллере и соответственно обновлять их, и вам нечего было бы изменить в вашем DisplayView, чтобы это произошло,

Шаблон делегирования

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

Ручное ведение списка объектов для уведомления

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

Заключение

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

Ответ 2

В дополнение к тем, которые перечислены Тони, который "возбуждает" событие, которое запускается при нажатии DisplayView на ближайший общий родительский вид DisplayView и EditView, есть еще один вариант. С событием вы передаете координаты отображения и модели, которые она представляет. Затем общий родитель прямо вызывает метод на EditView, чтобы переместить его и отобразить правильную модель. Таким образом, нет явных ссылок между параллельными представлениями и глобальными переменными.

Приостановка событий по нескольким уровням просмотров становится беспорядочной, используя магистраль, встроенную в методы trigger и listenTo, но плагин Backbone.Courier делает это очень просто:

https://github.com/rotundasoftware/backbone.courier

Ответ 3

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

События - это путь сюда.