rails 实时删除元素
rails remove element in real time
得到一个 link 从 current_users 屏幕上删除一条消息:
= link_to '[x]', msg, method: :delete, remote: true, class: "del-link"
它触发了这个 coffeescript-funktion:
delete_message = () ->
$('.del-link').on 'ajax:success', (event) ->
event.preventDefault()
$(this).closest('.message').remove()
return
和这个rails-方法:
def destroy
@msg = Msg.find(params[:id])
@msg.destroy
respond_to do |format|
format.html { redirect_to chat_path }
format.json { head :no_content }
format.js { render :layout => false }
end
end
但是如何做到这一点,即在每个用户屏幕上删除该消息,例如使用 ActionCable?
聊天的 coffeescript:
App.proom = App.cable.subscriptions.create "ProomChannel",
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
unless data.msg.blank?
$('#messages-table').append data.msg
scroll_bottom()
$(document).on "turbolinks:load", ->
submit_msg()
scroll_bottom()
delete_message()
channel.rb
class ProomChannel < ApplicationCable::Channel
def subscribed
stream_from "proom_channel"
end
def unsubscribed
end
end
方法
所以我将其添加到控制器的销毁操作中
if msg.destroy
ActionCable.server.broadcast 'proom_channel', msg: @msg
end
我还为每个包含消息记录 ID 的消息-div-元素添加了一个 ID,以便使用以下行 DOM 查找并删除它
$("msg_#{msg.id}").remove()
但是现在不知道放在哪里
我现在不能给你完整的答案,但如果你找不到解决方案,我会稍后更新我的答案:
就像您使用动作电缆创建消息一样,在将消息保存在数据库中后,您会触发一个 ActionCable.server.broadcast 'messages'
,它将执行一些包含在用户浏览器资产管道文件中的 JS app/assets/javascripts/channels/messages.js
]
这是我的消息控制器,一旦我保存消息,我就会启动 Server.broadcast
进程。它将触发我的 messages_channel.rb
中的进程,该进程将更新订阅该频道的所有客户端。
def create
message = Message.new(message_params)
message.user = current_user 
chatroom = message.chatroom
if message.save
ActionCable.server.broadcast 'messages',
message: message.content,
user: message.user.name,
chatroom_id: message.chatroom_id,
lastuser: chatroom.messages.last(2)[0].user.name
head :ok
end
end
图文来自以下文章Sophie DeBenedetto
We add our new subscription to our consumer with
App.cable.subscriptions.create. We give this function an argument of
the name of the channel to which we want to subscribe,
MessagesChannel.
When this subscriptions.create function is invoked, it will invoke the
MessagesChannel#subscribed method, which is in fact a callback method.
MessagesChannel#subscribed streams from our messages broadcast,
sending along any new messages as JSON to the client-side subscription
function.
Then, the received function is invoked, with an argument of this new
message JSON. The received function in turn calls a helper function
that we have defined, renderMessage, which simply appends new messages
to the DOM, using the $("#messages") jQuery selector, which can be
found on the chatroom show page.
频道将调用 messages.js
函数 received
,这会将 div 附加到 DOM,您需要在 messages.js
.
App.messages = App.cable.subscriptions.create('MessagesChannel', {
received: function(data) {
// code executed - the parameters will be in data.chatroom_id and
// data.user, data.message etc...
}
});
所以您需要从您的操作 messages#destroy
中调用频道,在 messages.js
中有一个特定的函数来从 DOM 中删除 div。
我不知道你是否需要创建一个特定的服务器端通道,或者你可以只编辑你现在的 messages_channel.rb
以包含一个特定的功能。你需要阅读指南并弄清楚这一点。我可以试试这在未来,但现在我不能
或者一个简单的替代方案,只需在 messages.js
中写一些 js 来解决这个问题,并在需要时删除 div.. 例如 messages#destroy
动作可以传递一个参数并且如果存在该参数,您将删除该消息,而不是添加它
https://github.com/rails/rails/tree/master/actioncable#channel-example-1-user-appearances
得到一个 link 从 current_users 屏幕上删除一条消息:
= link_to '[x]', msg, method: :delete, remote: true, class: "del-link"
它触发了这个 coffeescript-funktion:
delete_message = () ->
$('.del-link').on 'ajax:success', (event) ->
event.preventDefault()
$(this).closest('.message').remove()
return
和这个rails-方法:
def destroy
@msg = Msg.find(params[:id])
@msg.destroy
respond_to do |format|
format.html { redirect_to chat_path }
format.json { head :no_content }
format.js { render :layout => false }
end
end
但是如何做到这一点,即在每个用户屏幕上删除该消息,例如使用 ActionCable?
聊天的 coffeescript:
App.proom = App.cable.subscriptions.create "ProomChannel",
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
unless data.msg.blank?
$('#messages-table').append data.msg
scroll_bottom()
$(document).on "turbolinks:load", ->
submit_msg()
scroll_bottom()
delete_message()
channel.rb
class ProomChannel < ApplicationCable::Channel
def subscribed
stream_from "proom_channel"
end
def unsubscribed
end
end
方法
所以我将其添加到控制器的销毁操作中
if msg.destroy
ActionCable.server.broadcast 'proom_channel', msg: @msg
end
我还为每个包含消息记录 ID 的消息-div-元素添加了一个 ID,以便使用以下行 DOM 查找并删除它
$("msg_#{msg.id}").remove()
但是现在不知道放在哪里
我现在不能给你完整的答案,但如果你找不到解决方案,我会稍后更新我的答案:
就像您使用动作电缆创建消息一样,在将消息保存在数据库中后,您会触发一个 ActionCable.server.broadcast 'messages'
,它将执行一些包含在用户浏览器资产管道文件中的 JS app/assets/javascripts/channels/messages.js
]
这是我的消息控制器,一旦我保存消息,我就会启动 Server.broadcast
进程。它将触发我的 messages_channel.rb
中的进程,该进程将更新订阅该频道的所有客户端。
def create
message = Message.new(message_params)
message.user = current_user 
chatroom = message.chatroom
if message.save
ActionCable.server.broadcast 'messages',
message: message.content,
user: message.user.name,
chatroom_id: message.chatroom_id,
lastuser: chatroom.messages.last(2)[0].user.name
head :ok
end
end
图文来自以下文章Sophie DeBenedetto
We add our new subscription to our consumer with App.cable.subscriptions.create. We give this function an argument of the name of the channel to which we want to subscribe, MessagesChannel.
When this subscriptions.create function is invoked, it will invoke the MessagesChannel#subscribed method, which is in fact a callback method.
MessagesChannel#subscribed streams from our messages broadcast, sending along any new messages as JSON to the client-side subscription function.
Then, the received function is invoked, with an argument of this new message JSON. The received function in turn calls a helper function that we have defined, renderMessage, which simply appends new messages to the DOM, using the $("#messages") jQuery selector, which can be found on the chatroom show page.
频道将调用 messages.js
函数 received
,这会将 div 附加到 DOM,您需要在 messages.js
.
App.messages = App.cable.subscriptions.create('MessagesChannel', {
received: function(data) {
// code executed - the parameters will be in data.chatroom_id and
// data.user, data.message etc...
}
});
所以您需要从您的操作 messages#destroy
中调用频道,在 messages.js
中有一个特定的函数来从 DOM 中删除 div。
我不知道你是否需要创建一个特定的服务器端通道,或者你可以只编辑你现在的 messages_channel.rb
以包含一个特定的功能。你需要阅读指南并弄清楚这一点。我可以试试这在未来,但现在我不能
或者一个简单的替代方案,只需在 messages.js
中写一些 js 来解决这个问题,并在需要时删除 div.. 例如 messages#destroy
动作可以传递一个参数并且如果存在该参数,您将删除该消息,而不是添加它
https://github.com/rails/rails/tree/master/actioncable#channel-example-1-user-appearances