Версия 1:
Простой метод, который я на самом деле использовал в производстве: iframes.
Большую часть времени вам на самом деле все равно, будет ли страница отображаться одновременно и напрямую с сервера, и действительно, для нее лучше загружать в шахматном порядке.
Если вы просто добавите iframe src'd в действие show контроллера, у вас будет очень простое решение, которое не требует прямого взаимодействия между контроллерами.
Pro:
- очень легко
- работает с существующими действиями шоу и т. Д.
- может быть даже быстрее, в зависимости от экономии с параллельными или последовательными запросами, загрузкой памяти и т. Д.
Минусы:
- вы не всегда можете легко сохранить страницу вместе с тем, что есть
- iframes вырвется из пространства имен javascript главной страницы, поэтому, если они этого требуют, вам может понадобиться дать им их собственный минималистский макет; они также не смогут влиять на окружающую страницу за пределами своего iframe
- может быть медленнее, в зависимости от времени пинга и т. Д.
- потенциальная ошибка эффективности n + 1, если у вас много таких модулей на странице
Версия 2:
Сделайте то же самое, используя вызовы JS для замены div на частичное, как:
<div id="placeholder">
<%= update_page {|page| page['placeholder'].replace with some partial call here } %>
То же, что и выше, за исключением:
Pro:
- не блокирует его в iframe, поэтому разделяет контекст JS и т. Д.
- позволяет лучше обрабатывать случаи отказа
Con:
- требует JS и местозаполнителя div; немного сложнее
Версия 3:
Назовите целую кучу частичек. Это становится сложным, если вы говорите о таких вещах, как информационные панели, где отдельные модули обладают значительным количеством логики настройки.
Существуют различные способы обойти это, превращая эти вещи в «миксины» или тому подобное, но IMO, они немного глупы.
ETA: способ сделать это через mixins состоит в том, чтобы создать то, что по сути является библиотечным файлом, который реализует функции настройки контроллеров вашего модуля, включать его везде, где используется то, что вызывает их, и вызывать их.
Однако, у этого есть недостатки:
- Вы должны знать, какие действия контроллера верхнего уровня приведут к страницам, которые содержат эти модули (что может быть непросто, если это действительно сложные вещи, которые могут появляться повсюду, например, в зависимости от предпочтений пользователя)
- на самом деле он не действует как полноценный контроллер
- это все еще смешивает много логики, когда ваша вещь должна знать о том, что она держит
- Вы не можете легко разделить его на собственный контроллер, потому что он должен быть в файле библиотечного типа / mixin
Можно вызывать методы в одном контроллере из другого контроллера. Тем не менее, это большая боль в заднице и серьезный удар. Единственный раз, когда вам следует подумать об этом, - это если а) они оба независимо необходимые контроллеры со своими собственными правами и б) он должен полностью функционировать на серверной части.
Я должен был сделать это один раз - прежде всего потому, что рефакторинг причины был даже БОЛЬШЕ боли - и я обещаю, что вы не хотите идти туда, если вам не нужно.
Резюме
Лучший метод IMHO - первый, если у вас есть достаточно сложные вещи, которые требуют значительных настроек - простой iframe, который отображает модуль, передавая параметр, чтобы сказать ему использовать ультраминималистический макет (просто заголовки CSS + JS), потому что это не отображается как собственная страница.
Это позволяет вам сохранять вещи полностью независимыми, функционировать более или менее так, как если бы они были совершенно обычными собственными контроллерами (кроме настроек макета), сохранять нормальные маршруты и т. Д.
Если вам не нужны значительные настройки, просто используйте партиалы и передайте все, что им нужно, в качестве локальной переменной. Это начнет становиться хрупким, если вы столкнетесь с такими проблемами, как n + 1 ошибок эффективности, хотя ...