捕获 Rails 视图块时出现差异
Discrepancy when capturing Rails view block
我有一个包含两个块的 ERB 视图:
<%= test_h1 do %>
<%= 'test1' %>
<% end -%>
<%= test_h2 do %>
<%= 'test2' %>
<% end -%>
其中 test_h1
和 test_h2
是相似的助手,但一个是在助手文件中定义的,而另一个是通过 helper_method
在控制器中定义的:
module TestHelper
def test_h1(&block)
link_to '/url' do
capture(&block)
end
end
end
class TestController < ApplicationController
helper_method :test_h2
def test_h2(&block)
helpers.link_to '/url' do
helpers.capture(&block)
end
end
end
test_h1
产生预期结果,test_h2
首先呈现内部模板块:
<a href="/url">test1</a>
test2<a href="/url"></a>
为什么? test_h2
的惯用写法是什么?
我认为两个视图示例都应该重写为:
<%= test_h1 do %>
<% 'test1' %>
<% end -%>
<%= test_h2 do %>
<% 'test2' %>
<% end -%>
我的理解是“<%=”强制将块的输出渲染到输出流,这不是这两个示例中的预期行为
在 rails 中采用的惯用方法是将 test_h2 方法移动到一个关注点,并将该关注点包含在控制器和助手 class 中。
或者在您的控制器 class.
中将 test_h2 定义为 helper_method
但通常在多个地方需要的方法应该放在关注点中,并在需要的地方包括这些关注点。
此外,如果您需要视图的方法,请在帮助程序中包含关注点或定义您自己的方法。
参考 Can we call a Controller's method from a view (as we call from helper ideally)?
How to use concerns in Rails 4
当从你的控制器使用 capture
时,输出被附加到页面缓冲区,因此你的 erb 的 <%=
立即输出到页面输出。
要解决此问题,您需要在 test_h2
块中使用 <%
。因此,要在这两种情况下都获得预期的行为,请使用以下语法:
<%= test_h1 do %>
<%= 'test1' %>
<% end -%>
<%= test_h2 do %>
<% 'test2' %>
<% end -%>
capture
覆盖当前输出缓冲区并只调用块(仍然绑定到其他视图上下文),因此从控制器调用时覆盖无效,因为 view_context
不是相同的上下文正在渲染视图。
要解决上下文,您可以像这样定义您的助手:
# in controller
helper do
def test_h3(&block)
# this will run in view context, so call `controller.some_func` to access controller instance
link_to '/url' do
capture(&block)
end
end
end
我有一个包含两个块的 ERB 视图:
<%= test_h1 do %>
<%= 'test1' %>
<% end -%>
<%= test_h2 do %>
<%= 'test2' %>
<% end -%>
其中 test_h1
和 test_h2
是相似的助手,但一个是在助手文件中定义的,而另一个是通过 helper_method
在控制器中定义的:
module TestHelper
def test_h1(&block)
link_to '/url' do
capture(&block)
end
end
end
class TestController < ApplicationController
helper_method :test_h2
def test_h2(&block)
helpers.link_to '/url' do
helpers.capture(&block)
end
end
end
test_h1
产生预期结果,test_h2
首先呈现内部模板块:
<a href="/url">test1</a>
test2<a href="/url"></a>
为什么? test_h2
的惯用写法是什么?
我认为两个视图示例都应该重写为:
<%= test_h1 do %>
<% 'test1' %>
<% end -%>
<%= test_h2 do %>
<% 'test2' %>
<% end -%>
我的理解是“<%=”强制将块的输出渲染到输出流,这不是这两个示例中的预期行为
在 rails 中采用的惯用方法是将 test_h2 方法移动到一个关注点,并将该关注点包含在控制器和助手 class 中。
或者在您的控制器 class.
中将 test_h2 定义为 helper_method
但通常在多个地方需要的方法应该放在关注点中,并在需要的地方包括这些关注点。
此外,如果您需要视图的方法,请在帮助程序中包含关注点或定义您自己的方法。
参考 Can we call a Controller's method from a view (as we call from helper ideally)?
How to use concerns in Rails 4
当从你的控制器使用 capture
时,输出被附加到页面缓冲区,因此你的 erb 的 <%=
立即输出到页面输出。
要解决此问题,您需要在 test_h2
块中使用 <%
。因此,要在这两种情况下都获得预期的行为,请使用以下语法:
<%= test_h1 do %>
<%= 'test1' %>
<% end -%>
<%= test_h2 do %>
<% 'test2' %>
<% end -%>
capture
覆盖当前输出缓冲区并只调用块(仍然绑定到其他视图上下文),因此从控制器调用时覆盖无效,因为 view_context
不是相同的上下文正在渲染视图。
要解决上下文,您可以像这样定义您的助手:
# in controller
helper do
def test_h3(&block)
# this will run in view context, so call `controller.some_func` to access controller instance
link_to '/url' do
capture(&block)
end
end
end