当辅助方法使用yield关键字时,Rails部分模板会重复渲染
当使用带有部分布局的 Rails 以及使用 Yield 关键字编码为迭代器的辅助方法时,我看到了一些奇怪的行为。我希望有人能够:
- 解释发生了什么以及为什么我得到重复的渲染,也许
- 建议一种替代方法,希望不仅仅是将我的辅助方法重新编码为一个返回列表的简单函数(我已经这样做了)作为临时解决方法)
因此,如果我在 Rails 3 应用程序中创建以下 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/_partial.html.erb)
<% my_iterator do |x| %>
<p>iterator running with <%= x %></p>
<% end %>
当我在浏览器中查看结果时,我看到“iterator running with”块总共出现了 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 将辅助方法编码为迭代器?另外,有人可以准确解释重复渲染是如何发生的吗?
I have seen some strange behavior when using rails with partial layouts plus a helper method coded as an iterator using the yield keyword. I am hoping someone can:
- Explain what's going on and why I get the duplicate rendering and maybe
- Suggest an alternate approach, hopefully other than just re-coding my helper method to be a simple function that returns a list (I've already done that as an interim workaround)
So if I create the following 3 things in my rails 3 app, I get unexpected output.
[UPDATE]
I have tested the following combinations:
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)
So maybe it's an erb vs. haml thing, but when I initially discovered this it was on haml templates. Hmmm....anyone know what's going on???
A) A main template that looks like this (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) A helper method like this (app/helpers/main_helper.rb)
module MainHelper
def my_iterator
yield 1
yield 2
yield 3
yield 4
end
end
C) A partial template like this (app/views/main/_partial.html.erb)
<% my_iterator do |x| %>
<p>iterator running with <%= x %></p>
<% end %>
When I view the result in the browser, I see the "iterator running with" block a total of 8 times (1 2 3 4 1 2 3 4). I have determined it is the yield within my_iterator screwing with the rails partial template mechanism. If I code my_iterator as follows, the output is as I would expect. (I also need to change my partial template to do my_iterator.each)
def my_iterator
logger.debug("my_iterator called")
return [1, 2, 3, 4]
end
Is there a way to code this such that I don't screw with rails and get duplicate rendering but can still code a helper method as an iterator using yield? Also, can someone explain exactly how the duplicate rendering happens?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我刚刚遇到了一个非常相似的问题,并且设法解决了它。我相信如果重写上面的原始帮助器,它会按预期工作...
如果您调用
concat(capture(&block))
或,Rails 3 中似乎也会出现同样的问题concat(block.call)
。在这两种情况下,只需删除concat()
,重复的渲染就会消失。I was just having a very similar issue and just managed to solve it. I believe the original helper above would work as expected if rewritten it as such...
The same problem seems to occur in Rails 3 if your calling
concat(capture(&block))
orconcat(block.call)
. In both cases, just drop theconcat()
and the duplicate rendering vanishes.我遇到了类似的问题,该问题只出现在生产中,而不是开发中。我将其范围缩小到
我的development.rb。当设置为 true 时,我在 haml 文件中看到了一个元素。 违规代码的范围
通过添加和删除块,我缩小了导致重新打印之前的整个块的 。只需将 = 替换为 - 即可解决此问题。调试起来很尴尬,因为我必须在生产模式下进行调试。
我的建议是寻找逻辑运算符上错误的 = 输出。
I was experiencing a similar problem which only appeared in production, not development. I narrowed this down to
in my development.rb. When set to true, I saw a elements in my haml file. By adding and removing blocks I narrowed down the offending code to
which was causing the entire block which preceded this to be re-printed. Simply replacing = with - solves this. It was awkward to debug simply because I had to do in debug in production mode.
My advice is to look for errant = outputs on logical operators.
在助手中使用 content_for 将在每次迭代中附加内容。您可以编写一个 ApplicationHelper 方法来在帮助程序中生成内容,如下所示:
然后在其他帮助程序文件中使用 Yield_content 而不是 content_for 。
Using content_for within a helper will append content on each iteration. You can write a ApplicationHelper method to yield content within helpers like so:
Then use yield_content instead of content_for within your other helper files.