我有课
class DataListBuilder
include ActionView::Helpers::TagHelper
include ActionView::Helpers::CaptureHelper
include ActionView::Helpers::UrlHelper
attr_accessor :object, :output_buffer
def initialize(object)
@object, @output_buffer = object, nil
end
def column (&block)
if block_given?
content_tag(:li, block.call(self))
else
content_tag(:li, "")
end
end
def options_column(&link_block)
if block_given?
content_tag(:li, content_tag(:dl, "<dt><a href='#'> </a></dt><dd><ul>#{link_block.call(self)}</ul></dd>".html_safe, :class=>'options'))
else
content_tag(:li, "")
end
end
def link_item(title, url, options={})
content_tag :li, link_to(title, url, options)
end
end
并将其称为
<%= l.options_column do |c| %>
<%= c.link_item 'Show', lead_path(c.object) %>
<%= c.link_item 'Edit', edit_lead_path(c.object) %>
<%= c.link_item 'New Note', "leads/#{c.object.id}/notes/new", :class=>"display-newxdoc", :id=>c.object.id %>
<%= c.link_item 'Create Opportunity', new_lead_opportunity_path(c.object) %>
<% end %>
期望的输出是
<li><dl class="options"><dt><a href="#"> </a></dt><dd><ul style="display: none;">
<li><a data-remote="true" class="plus" href="leads/details/309"> </a></li>
<li>3w</li>
<li>Simon Wu</li>
<li>1-714-553-0888</li>
<li><a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c9a6a4a7a0babe89bca7a0afa0acadabaca8bde7aaa6a4" rel="noreferrer noopener nofollow">[email protected]</a></li>
<li>Unified Beat</li>
<li><a href="/leads/309">Show</a></li>
<li><a href="/leads/309/edit">Edit</a></li>
<li><a id="309" class="display-newxdoc" href="leads/309/notes/new">New Note</a></li>
<li><a href="/leads/309/opportunities/new">Create Opportunity</a></li>
但它正在生成
<li><a href="/leads/309">Show</a></li>
<li><a href="/leads/309/edit">Edit</a></li>
<li><a id="309" class="display-newxdoc" href="leads/309/notes/new">New Note</a></li>
<li><a href="/leads/309/opportunities/new">Create Opportunity</a></li>
<li><dl class="options"><dt><a href="#"> </a></dt><dd><ul style="display: none;">
<li><a data-remote="true" class="plus" href="leads/details/309"> </a></li>
<li>3w</li>
<li>Simon Wu</li>
<li>1-714-553-0888</li>
<li><a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="721d1f1c1b010532071c1b141b1716101713065c111d1f" rel="noreferrer noopener nofollow">[email protected]</a></li>
<li>Unified Beat</li>
<li><a href="/leads/309">Show</a></li>
<li><a href="/leads/309/edit">Edit</a></li>
<li><a id="309" class="display-newxdoc" href="leads/309/notes/new">New Note</a></li>
<li><a href="/leads/309/opportunities/new">Create Opportunity</a></li>
</ul></dd></dl></li>
</ul></dd></dl></li>
谁能帮我一下。
完整代码已列出here .
最佳答案
首先,我们重构了您的帮助程序,以便更频繁地使用 content_tag
(只是为了了解此代码中发生的情况 ^_^)。
接下来我们添加了 output_buffer
的用法,它已在帮助程序中定义但根本没有使用。
之后,所有应该从 erb
调用的方法都应该返回 nil
,这样它们就不会出现在 HTML 中。
最后一个语法糖是使用instance_eval
,所以你不需要{|c| ...}
样式 block 。您可以直接使用 DataListBuilder
中的所有变量。
module DataListHelper
def list_headers(args=[])
args = Array.new(args)
columns = []
args.map { |o| columns << content_tag(:li, o.split(":").first, :style=>"width:#{o.split(":").second}px;") }
content_tag(:ul, columns.join(" ").html_safe, :class=>"list-headers")
end
def data_list_total_records(array)
content_tag(:div, page_entries_info(array).html_safe, :class=>"total-records")
end
def data_list_for(object, headers=[], &block)
if object.is_a? Array
if object.length == 0
list_headers(headers).concat(content_tag(:strong, "<br />No records found".html_safe))
else
res_obj = data_list_total_records(object)
res_obj << content_tag(:ol, :class=>"data-list") do
res_ol = content_tag(:li) do
res = list_headers(headers)
object.each do |o|
builder = DataListBuilder.new(o)
res << content_tag(:li) do
content_tag(:ul, :id=>o.id, :class=>"list-row #{cycle('odd', 'even')}") do
capture(builder, &block)
builder.output_buffer.html_safe
end
end
end
res
end
res_ol << data_list_pagination(object)
end
res_obj
end
else
list_headers(headers).concat(content_tag(:strong, " <br />Not available."))
end
end
class DataListBuilder
include ActionView::Helpers::TagHelper
include ActionView::Helpers::CaptureHelper
include ActionView::Helpers::UrlHelper
include Rails.application.routes.url_helpers
attr_accessor :object, :output_buffer, :controller
def initialize(object)
@object, @output_buffer = object, ''
end
def column (&block)
@output_buffer << if block_given?
content_tag(:li, instance_eval(&block))
else
content_tag(:li, "")
end
nil
end
def options_column(&link_block)
@output_buffer << if block_given?
content_tag(:li) do
content_tag(:dl, :class=>'options') do
res = content_tag(:dt) do
content_tag(:a, ' '.html_safe, :href => '#')
end
res << content_tag(:dd) do
content_tag(:ul) do
instance_eval &link_block
end
end
end
end
else
content_tag(:li, "")
end
nil
end
def link_item(title, url, options={})
content_tag :li, link_to(title, url, options)
end
end
end
你的观点变成了这样:
<%= data_list_for @leads, [" :10", "Age:30", "Contact:140", "Phone:140", "Email:180", "Company:100", ""] do |l| %>
<%= l.column { link_to " ".html_safe, "leads/details/#{object.id}", :class=>:plus, :remote=>true } %>
<%= l.column { object.age } %>
<%= l.column { object.contact.complete_name } %>
<%= l.column { object.contact.phones.blank? ? "-" : object.contact.phones.first.phone_number } %>
<%= l.column { object.contact.emails.blank? ? "-" : object.contact.emails.first.email } %>
<%= l.column { object.company.title } %>
<%= l.options_column do %>
<%= link_item 'Show', lead_path(object.id) %>
<%= link_item 'Edit', edit_lead_path(object.id) %>
<%= link_item 'New Note', "leads/#{object.id}/notes/new", :class=>"display-newxdoc", :id=>object.id %>
<%= link_item 'Create Opportunity', new_lead_opportunity_path(object.id) %>
<% end %>
<% end %>
关于ruby-on-rails - 多级 block 方法正在产生问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5562658/