2012-09-15 80 views
2

我花了很多時間挖掘鏈輪和tit的源代碼,試圖找出如何將變量/綁定傳遞給Erb評估上下文。這是我想要做的:我需要提供一個JS文件,其內容根據每個請求進行更改。更改的部分取決於存儲在數據庫中的數據,因此需要通過Rails應用程序路由請求並需要傳遞變量/綁定。最重要的是,JS文件使用require指令插入其他JS文件,因此需要使用鏈輪。Sprockets>如何爲Erb評估/渲染指定綁定?

這裏是不工作的代碼片段:

Controller文件:

def ever_changing_js 
    @foobars = Foobar.all 
    MyApp::Application.assets.instance_eval do 
    def foobars 
     @foobars 
    end 
    end 

    render :text => MyApp::Application.assets.find_asset('ever_changing.js').to_s, :content_type => "application/javascript" 
end 

ever_changing.js:

//= require file1.js 
//= require file2.js 

// Some code that uses @foobars 

我怎樣才能得到這個工作?任何幫助,將不勝感激。

回答

0

JavaScript文件應該是完全靜態的;鏈輪不是爲了做你想做的事。

任何在每個請求基礎上發生變化的數據都應該寫入要渲染的模板底部的<script>標記。

應用程序/資產/ Java腳本/ user.js的

(function(exports) { 
    function User(name) { 
    this.name = name; 
    } 

    User.prototype.speak() { 
    console.log(this.name + ' says, "Hello!"'); 
    }; 

    exports.User = User; 
})(this); 

應用程序/視圖/用戶/ show.html.erb

... 

    <%= javascript_include_tag('user') %> 
    <script> 
    (function() { 
     var user = new User(<%= @user.name %>); 

     $('#speak-button').click(function() { 
     user.speak(); 
     }); 
    })(); 
    </script> 
</html> 

如果你可以給周圍更多的上下文您具體的用例,我可以舉一個更具體的例子。

+0

感謝您的回答ssorallen。不幸的是,在我的情況下沒有關聯的模板文件。讓我解釋。有問題的JS可被應用程序的各種用戶用於在其網站上呈現小部件。 (想想人們在他們的網站上安裝的實時聊天小部件)。現在每個用戶可能有不同的設置+需要被引用到JS文件中的數據。我想將JS的靜態部分和JS的動態部分封裝到一個文件中並提供它。這有意義嗎? –

+0

Google Maps等JavaScript API爲每個客戶端提供相同的JS,並要求客戶端實例化他們想要的對象和API。 –

+0

如果您真的*想要一個動態JavaScript文件,請將您的模板命名爲'.js.erb',並且Rails將爲請求返回JavaScript的正確MIME類型。它應該生活在'app/views'而不是'app/assets'中。 –

0

我正試圖完成同樣的事情,你是。我發現你的控制器代碼片段有一些問題。 Sprockets::Environment上的instance_eval不是,而應該是class_evalcontext_class,如Sprockets::Context documentation所示。

MyApp::Application.assets.context_class.class_eval do 
    def foobars 
    @foobars 
    end 
end 

然後foobars將可用於您的ERb模板。

一點題外話,你可以做

render js: MyApp::Application.assets.find_asset('ever_changing.js').to_s 

,而不是設置內容類型自己。