在 helper 的 content_tag 中循环和输出 content_tags
Posted
技术标签:
【中文标题】在 helper 的 content_tag 中循环和输出 content_tags【英文标题】:Loop & output content_tags within content_tag in helper 【发布时间】:2011-06-07 20:36:15 【问题描述】:我正在尝试一个辅助方法,它会输出一个项目列表,这样调用:
foo_list( ['item_one', link_to( 'item_two', '#' ) ... ] )
我在阅读Using helpers in rails 3 to output html之后写了这样的助手:
def foo_list items
content_tag :ul do
items.collect |item| content_tag(:li, item)
end
end
但是,在这种情况下,如果我将其作为测试,我只会得到一个空的 UL:
def foo_list items
content_tag :ul do
content_tag(:li, 'foo')
end
end
我按预期获得了 UL 和 LI。
我试着换了一点:
def foo_list items
contents = items.map |item| content_tag(:li, item)
content_tag( :ul, contents )
end
在这种情况下,我得到了整个列表,但 LI 标记是 html 转义的(即使字符串是 HTML 安全的)。执行content_tag(:ul, contents.join("\n").html_safe )
可行,但我觉得这有问题,我觉得content_tag
应该以某种方式在块模式下使用集合。
【问题讨论】:
【参考方案1】:试试这个:
def foo_list items
content_tag :ul do
items.collect |item| concat(content_tag(:li, item))
end
end
【讨论】:
那行得通,我之前尝试过在收集周围而不是在内部进行连接。使用 proc 内的 concat 则不需要 collect ,您可以使用 items.each (或其他迭代器)。 这样你就在每个元素上调用 concat 。我认为做 items.collect.join("").html_safe 会更便宜 你能解释一下 concat 在这里是如何工作的吗?我认为必须在另一个对象上调用 concat? @Tallboyconcat
在这里解释:api.rubyonrails.org/classes/ActionView/Helpers/…。该方法正在视图上下文中调用(我认为)。您可能会将其与 String#concat
混淆
谢谢,我之前找不到那个方法。这就解释了【参考方案2】:
我无法更好地完成这项工作。
如果你已经在使用HAML,你可以这样写你的助手:
def foo_list(items)
haml_tag :ul do
items.each do |item|
haml_tag :li, item
end
end
end
从视图中使用:
- foo_list(["item_one", link_to("item_two", "#"), ... ])
输出将是正确的。
【讨论】:
【参考方案3】:您可以使用content_tag_for
,它适用于集合:
def foo_list(items)
content_tag(:ul) content_tag_for :li, items
end
更新: 在 Rails 5 中,content_tag_for
(和 div_for
)被移到了单独的 gem 中。您必须安装 record_tag_helper
gem 才能使用它们。
【讨论】:
content_tag_for 在 Rails 5 中删除【参考方案4】:连同上面的答案,这对我很有效:
(1..14).to_a.each do |age|
concat content_tag :li, "#link_to age, '#'".html_safe
end
【讨论】:
执行此操作时可能需要将模板中的 【参考方案5】:最大的问题是 content_tag 在接收数组时没有做任何聪明的事情,您需要向它发送已经处理过的内容。我发现这样做的一个好方法是折叠/减少您的数组以将它们连接在一起。
例如,您的第一个和第三个示例可以使用以下内容代替您的 items.map/collect 行:
items.reduce(''.html_safe) |x, item| x << content_tag(:li, item)
作为参考,这是您在执行此代码时遇到的 concat 定义(来自 actionpack/lib/action_view/helpers/tag_helper.rb)。
def concat(value)
if dirty? || value.html_safe?
super(value)
else
super(ERB::Util.h(value))
end
end
alias << concat
【讨论】:
以上是关于在 helper 的 content_tag 中循环和输出 content_tags的主要内容,如果未能解决你的问题,请参考以下文章