rails实时删除元素

时间:2017-07-02 09:48:05

标签: javascript ruby-on-rails coffeescript actioncable

有一个链接可以从current_users屏幕中删除一条消息:

document.getElementsByClassName()

它触发了这个coffeescript-funktion:

var elements = document.getElementsByClassName('limittext');

for (var i = 0; i < elements.length; i++) {
  elements[i].addEventListener('focus', function() {
     limitTextArea(elements[i],2,0);
  });
}

和这个rails-method:

= link_to '[x]', msg, method: :delete, remote: true, class: "del-link"

但是如何在每个用户屏幕上删除该消息,例如,使用ActionCable?

聊天的coffeescript:

delete_message = () ->
$('.del-link').on 'ajax:success', (event) ->
  event.preventDefault()
  $(this).closest('.message').remove()
  return

channel.rb

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

方法

所以我把它添加到控制器的destroy-action

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()

我还为每个包含消息记录id的message-div-element添加了一个ID,以便使用以下行查找并从DOM中删除它

class ProomChannel < ApplicationCable::Channel
  def subscribed
    stream_from "proom_channel"
  end

  def unsubscribed
  end
end

但现在我不知道该把它放在哪里。

1 个答案:

答案 0 :(得分:2)

我现在无法给你完整答案,但如果你找不到解决方案,我会在稍后更新我的答案:

与使用操作电缆创建消息时一样,在DB中保存消息后,触发ActionCable.server.broadcast 'messages'将执行某些JS,例如在用户浏览器资产管道文件中app/assets/javascripts/channels/messages.js < / p>

这是我的消息控制器,保存消息后,我启动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

的以下文章
  

我们将新订阅添加到我们的消费者中   App.cable.subscriptions.create。我们给这个函数一个参数   我们要订阅的频道的名称,   MessagesChannel。

     

当调用这个subscriptions.create函数时,它会调用   MessagesChannel#subscribed方法,实际上是一个回调方法。

     

MessagesChannel#来自我们的消息广播的订阅流,   将任何新消息作为JSON发送到客户端订阅   功能

     

然后,调用接收到的函数,其参数为new   消息JSON。接收的函数依次调用辅助函数   我们已定义的renderMessage,它只是附加新消息   到DOM,使用$(“#messages”)jQuery选择器,可以   在聊天室节目页面上找到。

The Message Channel

频道会调用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中编写一些j来解决此问题并在需要时删除div。例如messages#destroy操作可以传递参数,如果存在该参数,你将删除该消息,而不是添加它

https://github.com/rails/rails/tree/master/actioncable#channel-example-1-user-appearances