代码之家  ›  专栏  ›  技术社区  ›  Peter Lyons

当helper方法使用yield关键字时,Rails部分模板重复呈现

  •  2
  • Peter Lyons  · 技术社区  · 14 年前

    当使用带有部分布局的Rails以及使用yield关键字编码为迭代器的助手方法时,我看到了一些奇怪的行为。我希望有人能:

    1. 解释发生了什么,为什么我得到了重复渲染,也许
    2. 建议一个替代方法,希望除了将helper方法重新编码为一个返回列表的简单函数(我已经做了这个临时解决方案)。

    因此,如果我在Rails3应用程序中创建以下3项内容,我会得到意想不到的输出。

    [更新] 我已经测试了以下组合:

    Rails 3.0.0 + erb (has this issue)
    Rails 3.0.0 + haml (OK)
    Rails 3.0.3 + erb (has this issue)
    Rails 3.0.3 + haml (OK)
    

    所以这可能是一个erb对haml的事情,但当我最初发现这是在haml模板。嗯……有人知道怎么回事吗????

    a)看起来像这样的主模板(app/views/main/index.html.erb)

      <h1>Main#index</h1>
      <p>This is content from main#index before the partial template rendering
      <%= render :partial => "partial" %>
      <p>This is content from main#index after the partial template rendering.</p>
    

    b)这样的助手方法(app/helpers/main_helper.rb)

      module MainHelper
    
        def my_iterator
          yield 1
          yield 2
          yield 3
          yield 4
        end
      end
    

    c)这样的部分模板(app/views/main/u partial.html.erb)

      <% my_iterator do |x| %>
      <p>iterator running with <%= x %></p>
      <% end %>
    

    当我在浏览器中查看结果时,我看到“迭代器与”块总共8次(1 2 3 4 1 2 3 4)。我已经确定它是我的_迭代器内的收益率,它与Rails部分模板机制一起使用。如果我按照下面的代码编写_迭代器,输出将如我所期望的那样。(我还需要更改我的部分模板来执行_迭代器。每个)

    def my_iterator
      logger.debug("my_iterator called")
      return [1, 2, 3, 4]
    end
    

    有没有一种方法可以这样编码:我不必使用Rails进行螺旋处理并获得重复的渲染,但仍然可以使用yield将助手方法编码为迭代器?另外,有人能准确地解释重复渲染是如何发生的吗?

    3 回复  |  直到 9 年前
        1
  •  3
  •   Jon Garvin    13 年前

    module MainHelper
      def my_iterator(&block)
        block.call(1)
        block.call(2)
        block.call(3)
        block.call(4)
      end
    end
    

    concat(capture(&block)) concat(block.call) concat()

        2
  •  1
  •   kjprice    9 年前

        config.action_view.cache_template_loading = true
    

        = if @user.bio
          = @user.bio
    

        - if @user.bio
          = @user.bio
    
        3
  •  0
  •   Archonic    12 年前

    def yield_content(content_key)
      view_flow.content.delete(content_key)
    end
    

    推荐文章