如何使用 jQuery 将值传递给 coffescript ActionCable
How to use jQuery to pass value into coffescript ActionCable
我正在尝试创建动态频道供用户聊天,但我无法将 room_id
传递到 room.coffee
文件中的 App.cable.subscriptions.create
调用中。澄清为什么我不能使用 jQuery 来获取值的任何帮助都非常有帮助。
这是我在控制台中收到的信息:
RoomChannel is transmitting the subscription confirmation
RoomChannel is streaming from room__channel
房间控制器
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
最简单的方法是将值作为数据属性传递给 HTML。然后用 jQuery.
从 CoffeeScript 读回
您可以将其添加到 messages
div 或表格中。像这样:
<div id="messages" data-room-id="<%= params[:id] %>">
并在 JavaScript 中阅读:
$('#messages').data('room-id')
原版 JavaScript:
document.getElementById('messages').dataset.roomId
将功能放在 $(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()
我正在尝试创建动态频道供用户聊天,但我无法将 room_id
传递到 room.coffee
文件中的 App.cable.subscriptions.create
调用中。澄清为什么我不能使用 jQuery 来获取值的任何帮助都非常有帮助。
这是我在控制台中收到的信息:
RoomChannel is transmitting the subscription confirmation
RoomChannel is streaming from room__channel
房间控制器
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
最简单的方法是将值作为数据属性传递给 HTML。然后用 jQuery.
从 CoffeeScript 读回您可以将其添加到 messages
div 或表格中。像这样:
<div id="messages" data-room-id="<%= params[:id] %>">
并在 JavaScript 中阅读:
$('#messages').data('room-id')
原版 JavaScript:
document.getElementById('messages').dataset.roomId
将功能放在 $(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()