【发布时间】:2015-03-01 00:43:14
【问题描述】:
我用 Ruby on Rails 编写的一个 Web 应用程序有很多使用的内容面板。我正在尝试编写帮助程序以使用更简洁的语法呈现这些面板。我对编写视图助手不是很熟悉,所以这可能很简单。但是,当尝试使用传递给块中的助手的“html”(erb 代码)时,我得到了奇怪的结果,其中块被渲染了两次。
相关代码如下。此示例使用 ERB,因为我对其进行了简化以避免任何可能的 HAML 问题,但我在使用 HAML 时得到了相同的结果。
我要渲染的 HTML 是:
<section class="panel panel-default">
<header class="panel-heading">Contacts</header>
<div class="panel-body">
<p>Test</p>
</div>
</section>
这是我的助手:
module ApplicationHelper
def panel(type = :default, &block)
tag = content_tag(:section, class: "panel panel-#{type.to_s}") do
block.call PanelHelper.new
end
tag
end
class PanelHelper
include ActionView::Helpers::TagHelper
include ActionView::Context
include ActionView::Helpers::CaptureHelper
def header(text = nil, &block)
if block_given?
tag = content_tag(:header, block.call, class: 'panel-heading')
elsif text
tag = content_tag(:header, text, class: 'panel-heading')
else
raise ArgumentError, 'Either a block must be given, or a value must be provided for the text parameter.'
end
tag
end
def body(&block)
content_tag(:div, block.call, class: 'panel-body')
end
end
end
这是我的看法:
<%= panel :default do |p| %>
<%= p.header 'Contacts' %>
<%= p.body do %>
<p>Test</p>
<% end %>
<% end %>
这是呈现的 HTML:
<section class="panel panel-default">
<header class="panel-heading">Contacts</header>
<p>Test</p>
<div class="panel-body">
<p>Test</p>
</div>
</section>
任何想法为什么会发生这种情况以及如何解决它?我可能只是对视图块有误解。
谢谢
编辑
我可以通过使用这个 body 方法让它发挥作用:
def body(&block)
@helper.concat tag(:div, class: 'panel-body').html_safe
block.call
@helper.concat '</div>'.html_safe
end
其中@helper 是PanelHelper 初始化程序中作为来自主帮助程序模块ApplicationHelper 的self 传递的。此外,我在调用 p.body 时删除了 =,因为我们正在直接写入缓冲区。
【问题讨论】:
标签: ruby-on-rails haml erb helpers