我正在尝试将Rails 2.3应用程序更新为更新的Rails版本(4/5) 我有一个方法,使用列表作为输入打印一个html表,调用者可以自定义行的显示。我还搜索了一些类似的东西,但它们并没有我需要的所有要求。所以我必须做这项工作。代码是
def model_table_2(collection, headers, options = {}, &proc)
options.reverse_merge!({
:id => nil,
:class => nil,
:style => nil,
:placeholder => 'Empty',
:caption => nil,
:summary => nil,
:footer => nil
})
placeholder_unless !collection.empty?, options[:placeholder] do
html_opt = options.slice(:id, :class, :style, :summary)
content_tag(:table, html_opt) do
table_sections = []
table_sections << content_tag(:caption, options[:caption]).to_s if options[:caption]
table_sections << content_tag(:thead,
content_tag(:tr,
headers.collect { |h|
concat(content_tag(:th, h))
}
)
)
if options[:footer]
table_sections << content_tag(:tfoot,
content_tag(:tr, content_tag(:th, concat(options[:footer]), :colspan => headers.size))
)
end
table_sections << content_tag(:tbody,
collection.each_with_index.collect do |row, row_index|
concat(
proc.call(row, cycle('odd', 'even'), row_index)
)
end.join
)
table_sections.join
end
end
end
def placeholder(message = t('general.empty'), options = {}, &proc)
# set default options
o = { :class => 'placeholder', :tag => 'p' }.merge(options)
# wrap the results of the supplied block, or just print out the message
if proc
t = o.delete(:tag)
concat tag(t, o, true), proc.binding
yield
concat "</#{t}>", proc.binding
else
content_tag o.delete(:tag), message, o
end
end
def placeholder_unless(condition, *args, &proc)
condition ? proc.call : concat(placeholder(args), proc.binding)
end
在视图文件中我称之为:
<% table_cols = ["No.", "Name"] %>
<% obj_list = [{active: true, name: 'First'}, {active: true, name: 'Second'}, {active: false, name: 'Last'}, nil] %>
<%= model_table_2(obj_list, table_cols, {:class=>'table table-bordered', :caption=>'Model Table Test', :footer=>'The Footer'}) do |record, klass, row_index| -%>
<% if !record.nil? then %>
<% content_tag :tr, :class => klass + (record[:active] ? '' : ' text-muted') do -%>
<td><%= row_index+1 -%></td>
<td><%= record[:name] %></td>
<% end %>
<% else %>
<% content_tag :tr, :class => klass do -%>
<td style="text-align:center;">*</td>
<td>render form</td>
<% end %>
<% end %>
<% end %>
但输出并不是我所期望的:
<table class="table table-bordered">
<th>No.</th>
<th>Name</th>
The Footer
<tr class="even">
<td>1</td>
<td>First</td>
</tr>
<tr class="odd">
<td>2</td>
<td>Second</td>
</tr>
<tr class="even text-muted">
<td>3</td>
<td>Last</td>
</tr>
<tr class="odd">
<td>*</td>
<td>render form</td>
</tr>
</table>
如您所见,某些标记遗失了,例如caption
,thead
,tbody
,tfoot
。我猜是因为content_tag
调用是嵌套的。我之前没有使用table_sections
数组,但它也没有工作。
此外,当列表为空时我出错,代码转到placeholder...
方法。
答案 0 :(得分:1)
这是一个奇怪的content_tag怪癖,但如果你嵌套它们,你需要use a concat on each return in the inner tags。否则,您只需获取最后返回的字符串,内部标记就会消失在以太网中。可悲的是,根据我的经验,我发现复杂的嵌套不值得进入辅助方法。
也许,更好的方法是使用装饰器模式,rails部分或使用类似cells gem之类的东西来干掉html。