我想在每次收到ajax请求时替换一组div(我正在处理的网站是完整的ajax ......)。例如,它可能是检查收件箱中的邮件数量,或显示用户统计信息......
问题是我不想在我的代码中多次重复这个对渲染函数的调用。
我试图在before_filter中调用我的函数,但是因为我调用了render:update,所以它第二次不起作用。
我尝试在application_controller中创建自己的函数render_page:
def render_page
render :update do |page|
yield(page)
# page.replace_html :div, ...
end
end
但不知怎的,上下文似乎丢失了:当我在控制器的函数上调用render_page时,我无法访问辅助函数......
谢谢!
答案 0 :(得分:2)
发现它!
我在rails文档中挖掘了一些ruby,以了解render:update函数的工作原理。
首先,我看到了渲染:更新只是通过发送代码块来调用update_page ...
http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html#method-i-update_page
此函数通过发送view_context(它只是ActionView :: Base的实例)来调用JavaScriptGenerator的构造函数。
JavaScriptGenerator.new(view_context, &block).to_s.html_safe
http://apidock.com/rails/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/new/class
在JavaScriptGenerator的构造函数中,我们可以观察
def initialize(context, &block) #:nodoc:
@context, @lines = context, []
include_helpers_from_context
@context.with_output_buffer(@lines) do
@context.instance_exec(self, &block)
end
end
instance_exec是一个ruby函数,允许在上下文中调用一个块......这正是我所需要的。
所以,解决方案(或至少一个工作解决方案......)是在application_controller中定义render_page:
def render_page(&block)
render :update do |page|
page << 'console.log("before_code");'
self.instance_exec(page, &block)
page << 'console.log("after_code");'
end
end
这样,而不是在我的控制器中调用
render :update do |page|
page.replace_html ...
helper_functions...
end
我打电话
render_page do |page|
page.replace_html ...
helper_functions...
end
我仍然可以调用我的辅助函数(因为已经传递了上下文)...