在使用部分布局的rails以及使用yield关键字编码为迭代器的辅助方法时,我看到了一些奇怪的行为。我希望有人可以:
因此,如果我在rails 3应用程序中创建以下3项内容,则会出现意外输出。
[UPDATE] 我测试了以下组合:
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 vs. 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 / _partial.html.erb)
<% my_iterator do |x| %>
<p>iterator running with <%= x %></p>
<% end %>
当我在浏览器中查看结果时,我看到“迭代器正在运行”块总共8次(1 2 3 4 1 2 3 4)。我已经确定它是my_iterator中与rails部分模板机制拧紧的产量。如果我按如下方式编码my_iterator,输出就像我期望的那样。 (我还需要将部分模板更改为my_iterator.each)
def my_iterator
logger.debug("my_iterator called")
return [1, 2, 3, 4]
end
有没有办法对此进行编码,这样我就不会使用rails并获得重复的渲染,但是仍然可以使用yield将辅助方法编码为迭代器?此外,有人可以确切地解释重复渲染是如何发生的吗?
答案 0 :(得分:3)
我只是遇到了一个非常类似的问题而且设法解决了这个问题。我相信上面的原始助手如果重写它就会按预期工作......
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)
,Rails 3中似乎也会出现同样的问题。在这两种情况下,只需删除concat()
,重复的渲染就会消失。
答案 1 :(得分:1)
我遇到了类似的问题,只出现在制作中,而不是开发中。我把它缩小到
config.action_view.cache_template_loading = true
在我的开发中.rb。设置为true时,我在haml文件中看到了一个元素。通过添加和删除块,我将违规代码缩小到
= if @user.bio
= @user.bio
导致重新打印之前的整个块。简单地替换= with - 解决这个问题。调试很尴尬因为我必须在生产模式下进行调试。
我的建议是在逻辑运算符上查找errant = outputs。
- if @user.bio
= @user.bio
答案 2 :(得分:0)
在帮助程序中使用content_for将在每次迭代时附加内容。您可以编写ApplicationHelper方法来生成帮助程序内的内容,如下所示:
def yield_content(content_key)
view_flow.content.delete(content_key)
end
然后在其他帮助文件中使用yield_content而不是content_for。