版本 1:
我在生产中实际使用的简单方法:iframe。
大多数情况下,您实际上并不关心页面是否一次全部呈现并直接从服务器呈现,实际上交错加载会更好。
如果您只是将 iframe src'd 放到控制器的显示操作中,那么您就有一个非常简单的解决方案,不需要直接的跨控制器交互。
临:
- 容易死
- 适用于现有的表演动作等
- 甚至可能更快,这取决于并行与顺序请求和内存负载等的节省
缺点:
- 您不能总是轻松地将页面与任何内容一起保存
- iframe 将脱离主机页面的 javascript 命名空间,因此如果它们需要,您可能需要为它们提供自己的简约布局;他们也无法影响其 iframe 之外的周围页面
- 可能会更慢,具体取决于 ping 时间等
- 如果页面上有许多这样的模块,则潜在的 n+1 效率错误
版本 2:
使用 JS 调用执行相同的操作,将 div 替换为部分内容,à la:
<div id="placeholder">
<%= update_page {|page| page['placeholder'].replace with some partial call here } %>
同上,除了:
临:
- 不会将其锁定到 iframe 中,因此共享 JS 上下文等
- 允许更好地处理故障情况
缺点:
版本 3:
调用一大堆部分。但是,一旦您谈论诸如仪表板之类的事情,其中各个模块具有大量设置逻辑,这样做就会变得复杂。
有多种方法可以通过将这些东西变成“mixins”或类似的东西来解决这个问题,但 IMO 他们有点笨拙。
ETA:通过 mixins 实现它的方法是创建本质上是一个库文件,它实现了模块控制器的设置功能,包括在任何使用调用 'em 的东西的地方,并调用 'em。
但是,这有缺点:
- 您必须知道哪些顶级控制器操作将导致包含这些模块的页面(如果这些确实是可能出现的小部件,例如依赖于用户偏好,那么您可能不容易)
- 它并不能真正充当成熟的控制器
- 它仍然混合了很多逻辑,你持有的东西需要知道它持有的东西
- 你不能轻易地将它隔离到它自己的控制器中,因为它需要在一个库类型的文件/mixin 中
可以从另一个控制器调用一个控制器中的方法。然而,这是一个主要的痛苦,也是一个主要的kludge。您唯一应该考虑这样做的情况是:a)它们都是独立必需的控制器,并且b)它必须完全在后端运行。
我不得不这样做一次 - 主要是因为重构它的原因更加痛苦 - 我保证你不想去那里,除非你必须这样做。
概括
最好的方法恕我直言,如果你有足够复杂的东西需要大量设置 - 一个简单的 iframe 显示模块,传递一个参数告诉它使用极简布局(只是 CSS + JS 标题),因为它没有被显示作为自己的页面。
这使您可以保持事物完全独立,或多或少地像它们自己的完全正常的控制器一样运行(除了布局设置),保留正常的路线等。
如果您不需要大量设置,则只需使用部分,并将所需的任何内容作为局部变量传递。但是,如果您遇到诸如 n+1 效率错误之类的问题,这将开始变得脆弱……