多级块方法产生问题 [英] Multi level block method is generating issue

查看:42
本文介绍了多级块方法产生问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有课

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='#'>&nbsp;</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="#">&nbsp;</a></dt><dd><ul style="display: none;">
    <li><a data-remote="true" class="plus" href="leads/details/309">&nbsp;</a></li>
    <li>3w</li>
    <li>Simon Wu</li>
    <li>1-714-553-0888</li>
    <li>omnisw@unifiedbeat.com</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="#">&nbsp;</a></dt><dd><ul style="display: none;">
    <li><a data-remote="true" class="plus" href="leads/details/309">&nbsp;</a></li>
    <li>3w</li>
    <li>Simon Wu</li>
    <li>1-714-553-0888</li>
    <li>omnisw@unifiedbeat.com</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>

有人能帮我吗.

完整代码在此处列出.

推荐答案

首先,我们重构了你的 helper 以更密集地使用 content_tag(只是为了了解这段代码中的内容^_^).

First of all we refactored your helper for more intensive usage of content_tag (just to get whats going in this code ^_^).

接下来我们添加 output_buffer 的用法,它在 helper 中定义但根本没有使用.

Next we add usage of output_buffer which was defined but not used at all in helper.

之后,所有应该从 erb 调用的方法都应该返回 nil 所以它们不会出现在 HTML 中.

After it all methods wich should be called from erb should return nil so they didn't appear in HTML.

最后一个句法suger是instance_eval的用法,所以你不需要{|c|...} 样式块.您可以直接使用 DataListBuilder 中的所有变量.

And last syntactic suger was usage of instance_eval so you don't need {|c| ...} style blocks. You can use all variables from DataListBuilder directly there.

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, '&nbsp;'.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 "&nbsp;".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 %>

这篇关于多级块方法产生问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆