【问题标题】:rails remove element in real timerails 实时移除元素
【发布时间】:2017-12-05 18:32:51
【问题描述】:

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

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

它触发了这个咖啡脚本功能:

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?

聊天的咖啡脚本:

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

频道.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 的 message-div-element 添加了一个 ID,以便使用以下行从 DOM 中查找和删除它

$("msg_#{msg.id}").remove()

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

【问题讨论】:

    标签: javascript ruby-on-rails coffeescript actioncable


    【解决方案1】:

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

    就像您使用操作电缆创建消息一样,在将消息保存到 DB 后,您会触发一个 ActionCable.server.broadcast 'messages',它将执行一些 JS,例如包含在用户浏览器资产管道文件 app/assets/javascripts/channels/messages.js 中的一些 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以下文章

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

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

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

    然后,调用接收到的函数,并带有这个新的参数 消息 JSON。接收到的函数依次调用辅助函数 我们定义的,renderMessage,它只是附加新消息 到 DOM,使用 $("#messages") jQuery 选择器,它可以是 在聊天室显示页面上找到。

    频道将调用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

    【讨论】:

    • 似乎有一些编辑失误,因为在第一个代码块之后重复了开头段落。
    • @vijoc 我不明白你的意思
    • 我认为您错误地将前两段粘贴到第一个代码块中
    • 现在它在它下面,但它仍然是一个重复
    • @FabrizioBertoglio 请看看我更新的问题
    猜你喜欢
    • 1970-01-01
    • 2014-05-06
    • 2019-05-27
    • 2017-12-12
    • 1970-01-01
    • 2013-02-07
    • 2013-04-22
    • 2011-07-15
    • 1970-01-01
    相关资源
    最近更新 更多