【问题标题】:Rails 3 and partials layoutsRails 3 和局部布局
【发布时间】:2012-03-16 09:18:54
【问题描述】:

我正在尝试为每个对象以相同的格式呈现不同对象的集合。我想让它保持干燥,所以我想使用部分和partial layouts

编辑 - 简要说明:我需要的不是在所有发布页面上显示通用项目,而是在每个项目上显示通用属性/字段。这就是为什么我需要部分布局,例如部分布局,而不是页面布局。

我有一个不同对象的集合:

@publications = Publications.all
# Publication is the parent class
# @publications = [ImagePost, VideoPost, TextPost, ...]

我想呈现一个列表中的所有出版物。每个出版物都有一些共同的属性:作者、日期、...我想把这些属性放在一个部分布局中。

所以在我看来,要渲染集合,我会这样做:

<%= render :partial => 'publications', :locals => {:publications => @publications} %>

在第一级部分views/publications/_publications.html.erb 中,我在项目上循环并尝试在其部分中呈现每个项目并使用公共部分布局:

<ul class='publications_list'>
  <% publications.each do |p| %>
    <%= render p, :layout => 'publications/publication_layout' %>
  <% end %>
</ul>

部分布局,views/publications/_publication_layout.html.erb

<li>
  <h2><%= link_to publication.title, publication %></h2>
  ... Other common properties that I want to display on each item, independently of its type ...
  <p><%= yield %></p>
</li>

最后,对于每种对象类型,我都有一个部分(例如image_posts/_image_post.html.erb 等)包含正确显示的代码。

我的问题:我无法以通用部分布局 publication_layout 呈现每个出版物。这种布局被rails简单地忽略了。每个项目都正确呈现,但没有包含公共属性和 &lt;li&gt; 标记的布局。

关于为什么我的部分布局被忽略的任何建议?

【问题讨论】:

  • 您是否尝试按照指南建议的方式直接指定 :partial ? “另请注意,在传递附加选项(例如 :layout)时需要显式指定 :partial。”.
  • 请参阅apidoc 了解扩展文档。
  • 很好,这可以解释整个事情......这种行为真的很奇怪而且不直观。这对我来说不是很方便,因为 polymorphic 集合(部分取决于p 的类型)。关于如何以优雅而简短的方式检索每个对象的好部分的任何想法?
  • @MarkGuk 所以我找到了解决方法,详情请参阅我的答案。感谢您的贡献。如果您想获得赏金,请回答。

标签: ruby-on-rails ruby-on-rails-3 partials


【解决方案1】:

我想知道nested layout 是否可以在这里为您提供更好的服务。该指南应该为您指明正确的方向,我发现开始工作非常容易,但作为一个开始:

views/layouts/application.html.erb 中,将yield 更改为:

<%= content_for?(:publication_content) ? yield(:publication_content) : yield %>

消除部分views/publications/_publication.html.erb,改为创建嵌套布局views/layouts/publication.html.erb

<% content_for :content do %>
    # Put common items here
    <%= content_for?(:content) ? yield(:content) : yield %> # this is for specifics
<% end %>

<%= render :template => 'layouts/application' %>

然后可以进一步嵌套特定布局或在视图中使用其他标签指定,具体取决于您的其余设置。

【讨论】:

  • 嗯,我考虑过嵌套布局(并且我知道如何使用它),但是 1/我想尝试一下为这种特定用途而设计的局部布局,而 2/我没有看到如何让它在这里为我工作。更准确地说,我看不到如何重复布局超过 1 次以呈现 collection 而不是单个项目(如您的示例所做的那样)。更准确地说,我再次指出我的集合是多态的(在面向对象编程的意义上)
  • 您可以使用带有嵌套布局的部分来显示集合;至少我在我的应用程序中没有问题。发布布局中的yield 部分将显示该视图上指定的任何内容,因此您可以非常轻松地融入您已经设置的部分系统。嵌套布局部分主要是您希望在所有出版物页面上显示的常见项目的解决方案。
  • 不,真的,我没有得到你的答案和我的问题之间的联系;)我需要的不是在所有发布页面上显示常见项目,而是显示常见属性/字段 在每个项目上。这就是为什么我需要partial layouts 例如部分布局,而不是页面布局。您的解决方案只是告诉我如何进行发布页面布局...
  • 我试图对我的问题做一些澄清,请再读一遍。
【解决方案2】:

答案和解决方法

感谢@MarkGuk 在文档中发现了这一行:

另请注意,传递时需要显式指定 :partial 附加选项,例如 :layout。

因此,不可能简单地在每个项目的相同部分中呈现多态集合。

解决方法 1: 我首先尝试计算每个项目的部分路径,将其存储在模型中以方便使用,然后以良好的布局渲染每个项目。但是我意识到这个方法,我不能引用布局里面的对象publication...

<ul class='publications_list'>
  <% publications.each do |p| %>
    <% # p.partial = p.class.to_s.underscore.pluralize +'/'+ p.class.to_s.underscore %>
    <%= render :partial => p.partial, :object => p, :as => :publication, :layout => 'publications/publication_layout' %>
  <% end %>
</ul>

解决方法 2: 最后我使用了嵌套的部分。

<ul class='publications_list'>
  <% publications.each do |p| %>
    <%= render :partial => 'publications/publication_layout', :object => p, :as => :publication %>
  <% end %>
</ul>

并在布局内将yield 替换为render publication

【讨论】:

    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 2017-05-02
      • 2011-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多