在helper中的content_tag内循环并输出content_tags

DEf*_*ion 29 ruby-on-rails block helper ruby-on-rails-3

我正在尝试一个帮助方法,它将输出一个项目列表,如下所示:

foo_list( ['item_one', link_to( 'item_two', '#' ) ... ] )
Run Code Online (Sandbox Code Playgroud)

我在阅读了使用rails 3中的helper输出html之后,就像这样编写了帮助器:

def foo_list items
    content_tag :ul do
        items.collect {|item| content_tag(:li, item)}
    end
end
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做,我只是在这种情况下得到一个空的UL:

def foo_list items
    content_tag :ul do
        content_tag(:li, 'foo')
    end
end
Run Code Online (Sandbox Code Playgroud)

我按预期获得了UL和LI.

我已经尝试过将它交换一下:

def foo_list items
    contents = items.map {|item| content_tag(:li, item)}
    content_tag( :ul, contents )
end
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我得到整个列表,但LI标签是html转义(即使字符串是HTML安全).做的content_tag(:ul, contents.join("\n").html_safe )工作,但我感觉不对,我觉得content_tag应该以块模式与集合以某种方式工作.

zet*_*tic 51

试试这个:

def foo_list items
  content_tag :ul do
      items.collect {|item| concat(content_tag(:li, item))}
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 这样你就可以在每个元素上调用concat.我认为做items.collect {}.join("").html_safe会更便宜 (3认同)
  • @Tallboy `concat` 的解释如下:http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-concat。该方法是在视图上下文上调用的(我认为)。您可能会将它与“String#concat”混淆 (2认同)

Hei*_*kki 8

我无法更好地完成这项工作.

如果您已经使用HAML,您可以像这样编写助手:

def foo_list(items)
  haml_tag :ul do
    items.each do |item|
      haml_tag :li, item
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

用法视图:

- foo_list(["item_one", link_to("item_two", "#"), ... ])
Run Code Online (Sandbox Code Playgroud)

输出将是正确的意图.


Dan*_*ski 5

你可以使用content_tag_for,它适用于集合:

def foo_list(items)
  content_tag(:ul) { content_tag_for :li, items }
end
Run Code Online (Sandbox Code Playgroud)

更新:在Rails 5中,content_tag_for(和div_for)被移动到一个单独的gem中.您必须安装record_tag_helpergem才能使用它们.