如何利用Action Cable获取的数据渲染Rails局部视图?
在Action Cable中利用数据渲染Rails局部视图
嘿,我懂你现在已经通过Action Cable拿到了消息数据,想要用Rails的局部视图来渲染它对吧?这里有几种实用的方法可以实现:
方法一:后端直接返回渲染好的HTML(推荐)
最简单高效的方式,就是在你的TransactionMessageChannel里,把局部视图提前渲染成HTML字符串,和消息数据一起广播出去。这样前端拿到的data里就有现成的HTML,直接插入DOM就行。
比如在你的Channel类里添加广播逻辑:
# app/channels/api/v1/transaction_message_channel.rb def broadcast_message(message) # 渲染局部视图为HTML字符串 message_html = ApplicationController.render( partial: 'api/v1/transaction_messages/message', locals: { message: message } ) # 把原始数据和渲染好的HTML一起广播 ActionCable.server.broadcast( "transaction_#{params[:transaction_id]}_channel", user: message.user.as_json, html: message_html ) end
然后前端的received方法里直接用这个HTML:
received: function(data) { // 直接把后端渲染好的HTML插入聊天区域 $(".chat-area ul").append(data.html); // 也可以保留你原来的alert逻辑 alert(data["user"]["full_name"]); }
方法二:前端通过AJAX请求获取渲染后的HTML
如果不想在后端提前渲染,也可以前端拿到数据后,发一个AJAX请求到专门的控制器动作,让Rails渲染局部视图并返回HTML。
首先创建一个控制器动作:
# app/controllers/api/v1/transaction_messages_controller.rb def render_message message = TransactionMessage.find(params[:id]) render partial: 'api/v1/transaction_messages/message', locals: { message: message } end
别忘了在路由里添加这个动作:
# config/routes.rb namespace :api do namespace :v1 do resources :transaction_messages, only: [] do get :render_message, on: :member end end end
然后前端的received方法里发起请求:
received: function(data) { alert(data["user"]["full_name"]); // 请求渲染好的局部视图HTML $.get(`/api/v1/transaction_messages/${data.id}/render_message`, function(html) { $(".chat-area ul").append(html); }); }
方法三:使用Rails的JS模板(适合复杂交互)
如果需要在渲染后执行更多JS逻辑,可以创建.js.erb模板,让Rails帮你整合渲染和交互逻辑。
比如在app/views/api/v1/transaction_messages/下创建append_message.js.erb:
// 渲染局部视图并插入DOM $(".chat-area ul").append("<%= j render partial: 'api/v1/transaction_messages/message', locals: { message: @message } %>"); // 还可以加一些额外的交互逻辑,比如滚动到最新消息 $(".chat-area").scrollTop($(".chat-area")[0].scrollHeight);
然后在控制器里添加对应的动作:
def append_message @message = TransactionMessage.find(params[:id]) render layout: false end
最后前端received方法里请求这个模板:
received: function(data) { alert(data["user"]["full_name"]); // 加载并执行JS模板 $.getScript(`/api/v1/transaction_messages/${data.id}/append_message`); }
这几种方法里,第一种是最推荐的——不需要额外的AJAX请求,广播时就把HTML准备好,性能更优。
内容的提问来源于stack exchange,提问作者Ian Tran
相关产品推荐
相关产品推荐

