2011-08-10 124 views
2

我想在每次收到一個ajax請求(我正在使用的網站是完整的ajax ...)時替換一組div。例如,它可能正在檢查收件箱中的郵件數量,或者顯示用戶統計信息...渲染前調用函數

事情是我不想在我的代碼中多次重複對我的呈現函數的調用。

我試圖在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,我無法訪問輔助功能...

謝謝!

+1

不是一個答案,但如果你想訪問控制器中的助手,你必須包括他們:'include RoutesHelper'。編輯:但你確定這應該在你的控制器操作中被調用?我認爲page.replace_html應該在你的.js.erb文件中調用... – Robin

+0

從技術上講,它可以工作,但我知道這對MVC組織不好...但問題仍然存在;是否有可能在每個.js.erb文件的末尾執行相同的代碼部分,而沒有任何重複? – sdrdis

回答

2

找到了!

我在Rails文檔中挖了一點紅寶石,以瞭解render:update函數的工作原理。

首先,我看到了渲染:更新是隻需發送代碼塊調用update_page ...

http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html#method-i-update_page

而這個功能是通過發送view_context調用JavaScriptGenerator的構造函數(這僅僅是ActionView :: Base實例)。

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是紅寶石功能,允許調用上下文中的塊......那是什麼我需要。

所以,解決(或至少一個有效的解決方案......)是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 

而我仍然允許編輯呼叫我的幫助功能(因爲上下文已通過)...