[英]Include a Coffeescript file with ERB in a view
這讓我很頭疼......
所以我有一個應用程序,需要一個側邊欄,列出與用戶的播放器有關的各種信息。 這個側邊欄的一部分是朋友列表。 現在,當玩家A向玩家B發送朋友請求時,該請求應自動記錄在B的側邊欄中,我打算使用WebSockets來執行此操作。
這是我的cp.js.coffe.erb
文件(目前只有幾個ERB片段;會有更多的加載,我寧願cp.js.coffe.erb
先工作):
$ ->
$("#cp").accordion()
if `"WebSocket" in window`
socket = new WebSocket("ws://localhost:8080")
socket.onopen = =>
console.log("Connection Open")
init = {
sender: "cp"
action: "init"
user: <%= @user.id %>
token: <%= cookies["remember_token"] %>
}
socket.send(init.to_json)
socket.onerror = (e)=>
console.log(e)
socket.onclose = =>
console.log("Closed")
socket.onmessage = (m)=>
console.log("Recieved: #{m.data}")
msg = m.data.JSON.parse
switch msg.action
when "ret_init"
when "friend_udt"
refreshFriend()
refreshFriend() ->
html = "<%= j render 'layouts/friends' %>"
$('#friends').empty()
$('#friends').add(html)
從理論上講,代碼本身工作正常,問題就在於此 Rails不允許您在資產管道中使用ERB,因此該文件必須位於 該文件無法訪問控制器中聲明的變量或使用app/views/layouts
。 render
方法(或大多數其他ERB方法)。
事情就是這樣:我不能在我的application.html.erb
文件中包含所述文件,而是考慮用AJAX請求文件,但據我所知,這將立即執行一次Javascript,我需要方法在此可以隨時更新側邊欄。
是否有任何方法可以包含此文件,以便它可以與ERB和CoffeScript一起使用,以便它可以持續提供給頁面? 我誤解了整個AJAX請求方法嗎?
<ul id="friendlist"> <% if Relation.find_by(owner: @user.id, type: "freq") != nil %> <% Relation.find_by(owner: @user.id, type: "freq").each do |r| %> <li class="friend-request-cp"><%= link_to "/#{User.find(r.character).name}" %></li> <% end %> <% end %> <% if Relation.find_by(owner: @user.id, type: "friend") != nil %> <% Relation.find_by(owner: @user.id, type: "friend").each do |r| %> <li class="friend-cp"><%= link_to "/#{User.find(r.character).name}" %></li> <% end %> <% end %> </ul>
我需要為每個項目應用兩種不同的樣式,因此我在這里使用ERB。 這工作正常,因為它是在頁面首次導航時加載的,但我的代碼應該在每次通知任何新的交互時重新呈現該部分。 然后,它將再次使用數據庫中的數據重新填充列表。 有更有效的方法嗎? 我還能用你給我看的hamlcoffeeassets
寶石做到這一點嗎?
你可以在資產管道中使用erb
,但是你必須記住它只會被渲染為ONCE,EVER,而不是每個用戶都被渲染一次,所以即使有@user
變量(也沒有),它也是永遠不會改變。 您可以在咖啡文件中使用erb
來處理路徑路徑和環境變量,但不能用於特定於用戶的配置和JS的動態更改。 無論如何,這是不好的做法。
你應該做的是使用一個javascript庫來讀取cookie而不是嘗試使用rails(這將使你能夠訪問你似乎試圖做的一些事情)。 當您需要更多動態行為時,您應該將數據屬性或其他值呈現到html DOM本身並使用javascript來讀取它。
看看這個cookie庫: https : //github.com/carhartl/jquery-cookie
還有很多其他人可以通過快速谷歌搜索來查看。
socket.onopen = =>
console.log("Connection Open")
init = {
sender: "cp"
action: "init"
user: $.cookie('user_id')
token: $.cookie('remember_token')
}
有幾種方法可以使用JS為視圖呈現新標記。 一種方法是使用js模板。 我是這里hamlcoffeeassets
庫的忠實粉絲: https : //github.com/netzpirat/haml_coffee_assets雖然它使用haml作為視圖,而不是ERB。 還有ERB變種。
你可以添加一些標記到app/assets/templates/friend.jst.hamlc
如下所示:
%p This is my friend markup #{@friend.name}
然后你可以像這樣從你的JS渲染它:
$('#friends').append(JST['templates/friend'](friend: {name: 'Bob'}))
這將使用您插入的值附加模板中的標記。在我的示例中,您最終會在#friends
容器中使用此標記:
<p>This is my friend markup Bob</p>
或者,您可以通過rails將您想要的部分渲染到JSON響應中,只需要一個字符串,然后將其插入到文檔中......
所以你的JS可能看起來像這樣:
socket.onmessage = (m)=>
console.log("Recieved: #{m.data}")
msg = m.data.JSON.parse
switch msg.action
when "ret_init"
when "friend_udt"
refreshFriend(msg.friendHTML)
refreshFriend(html) ->
$('#friends').html(html)
UPDATE
關於你的ERB問題...首先你的部分是非常低效的,每次你渲染它時,對數據庫進行四次類似的調用。 haml_coffee_assets
用於haml
標記語言(我更喜歡ERB),如果你想要ERB然后使用eco代替: https : //github.com/sstephenson/eco
如果你想在JS中渲染它,那么你需要通過通知數據響應發送這個“朋友關系”數據作為JSON,你在渲染javascript部分時無法訪問活動記錄或任何控制器方法或實例變量 - 他們不要回到服務器,他們只使用你當時可以訪問的javascript。
這應該真的去app/assets/javascripts/cp.js.coffee.erb
,你可以在資產管道中使用erb就好了(見這里 )確保你拼寫正確的coffee
擴展名!
這樣做,你應該可以通過ajax調用它沒有問題,路徑將是/assets/cp.js
。
試試這個寶石:' coffeebeans '
將您的咖啡文件命名為“some_file.html.erb”
<%= coffeescript_tag_do %> # your coffee script here ... <% end %>
在另一個erb文件中:
<%= render file: '.../some_file' %>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.