【问题标题】:How to use jQuery to pass value into coffescript ActionCable如何使用 jQuery 将值传递给 coffescript ActionCable
【发布时间】:2018-01-22 23:37:58
【问题描述】:

我正在尝试为用户创建动态聊天频道,但我无法将room_id 传递到room.coffee 文件中的App.cable.subscriptions.create 调用。澄清为什么我不能使用 jQuery 来获取值的任何帮助都非常有帮助。

这是我在控制台中收到的回复:

RoomChannel is transmitting the subscription confirmation
RoomChannel is streaming from room__channel

RoomsController

class RoomsController < ApplicationController
  before_action :authenticate_user!

  def show
    other_user = User.find(params[:id])
    title = [other_user.id.to_s, current_user.id.to_s].sort!.join("-")
    @room = Room.where(title: title).first
    if @room.nil?
      @room = Room.create! title: title
    else
      @messages = Message.where(room_id: @room[:id])
    end
  end

end

show.html.erb

<h1>Chat Room</h1>
<div id="messages">
  <% if @messages.blank? %>
    <div id="no_messages_yet">
      <p>No messages yet...</p>
    </div>
  <% else %>
      <%= render @messages %>
  <% end %>
</div>
<form>
  <label>Say something:</label><br>
  <input type="text" data-behavior="room_speaker">
  <input type="hidden" value="<%= @room[:id] %>" id="room_id">
  <input type="hidden" value="<%= current_user[:id] %>" id="user_id">
</form>

views/messages/_message.html.erb

<div class="message">
  <p><%= message.content %></p>
</div>

room.coffee

$(document).ready ->
  room_id = $("#room_id").val()
  console.log(room_id)
  // => 1
  // When I try and pass 'room_id' as the value for room_id:, I get an error stating the variable is not recognized.
App.room = App.cable.subscriptions.create {channel: "RoomChannel", room_id: $('#room_id').val()},
  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) ->
    $('#messages').append data['message']
    # Called when there's incoming data on the websocket for this channel

  speak: (message, room_id, user_id) ->
    @perform 'speak', message: message, room_id: room_id, user_id: user_id

$(document).on 'keypress', '[data-behavior~=room_speaker]', (event) ->
  if event.keyCode is 13 # return = send
    App.room.speak event.target.value, $('#room_id').val(), $('#user_id').val()
    event.target.value = ""
    event.preventDefault()

房间频道

class RoomChannel < ApplicationCable::Channel
  def subscribed
    stream_from "room_#{params[:room_id]}_channel"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def speak(data)
    m = Message.new
    m.user_id = data["user_id"]
    m.room_id = data["room_id"]
    m.content = data["message"]
    m.save!
  end
end

message.rb

class Message < ApplicationRecord
  after_create_commit { MessageBroadcastJob.perform_later self }
end

jobs/message_broadcast_job.rb

class MessageBroadcastJob < ApplicationJob
  queue_as :default

  def perform(message)
    ActionCable.server.broadcast "room_#{message.room_id}_channel", message: render_message(message)
  end

  private
  def render_message(message)
    ApplicationController.renderer.render(partial: 'messages/message', locals: { message: message })
  end
end

【问题讨论】:

    标签: jquery ruby-on-rails coffeescript actioncable


    【解决方案1】:

    最简单的方法是将值作为数据属性传递给 HTML。并使用 jQuery 从 CoffeeScript 中读取。

    您可以将其添加到messages div 或表单中。像这样的:

    <div id="messages" data-room-id="<%= params[:id] %>">
    

    在 JavaScript 中,阅读它:

    $('#messages').data('room-id')
    

    在原生 JavaScript 中:

    document.getElementById('messages').dataset.roomId
    

    【讨论】:

    • 感谢您的帮助,但不幸的是,没有 jQuery 调用适用于代码的特定部分。
    • 我添加了香草 JS 版本。请检查。
    • 这引发了错误:Uncaught TypeError: Cannot read property 'dataset' of null
    • 您应该将 JS 放在页脚或 document.ready 事件中。否则 HTML 会在 JS 之后渲染,会报错。
    • 我实际上尝试使用您的解决方案和我的解决方案都这样做,但它给出了一个错误:Uncaught ReferenceError: room_id is not defined 当我尝试使用值传递变量时。在进行App.room = App.cable.subscriptions.create 调用之前,我可以看到该值并在控制台记录它,但不能将变量作为参数传递。
    【解决方案2】:

    将功能放在$(document).ready 调用中。请记住,coffeescript 在缩进和空白方面非常敏感。

    $(document).ready ->
      room_id = $('#room_id').val()
      App.room = App.cable.subscriptions.create {channel: "RoomChannel", room_id: room_id},
    
        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) ->
          $('#messages').append data['message']
          # Called when there's incoming data on the websocket for this channel
    
        speak: (message, room_id, user_id) ->
          @perform 'speak', message: message, room_id: room_id, user_id: user_id
    
    $(document).on 'keypress', '[data-behavior~=room_speaker]', (event) ->
      if event.keyCode is 13 # return = send
        App.room.speak event.target.value, $('#room_id').val(), $('#user_id').val()
        event.target.value = ""
        event.preventDefault()
    

    【讨论】:

      猜你喜欢
      • 2013-01-06
      • 2019-10-12
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多