订阅Action Cable频道时如何设置参数
How to set params when subscribing to Action Cable channel
似乎几个月来,我一直在努力研究动作电缆。请帮忙。
我有一个 "Connection" - 我无法设置 identified_by :current_user
因为这个端点也需要被使用 WebSockets 的外部 API 使用。无法使用浏览器 cookie 来验证 API 端点。
文件与支持
连接:/app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
end
end
频道:/app/channels/application_cable/channel.rb
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
我有一个特定的访问渠道:/app/channels/visits_channel.rb
class VisitChannel < ApplicationCable::Channel
def subscribed
stream_from "visit_#{params[:visit_id]}"
end
end
然后我有我的 coffeescript 频道:/app/assets/javascripts/channels/visit.coffee
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: '42' },
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) ->
console.log data
push: ->
@perform 'push'
然后我的访问模型回调:/app/models/visit.rb
class Visit < ApplicationRecord
after_save :push_to_action_cable
**** detail of model removed ****
def push_to_action_cable
ActionCable.server.broadcast("visit_#{self.id}", self)
end
end
这是完美的,它每次都将对象放到控制台,并且只有 ID 为 42
的对象
这是我的问题:
在 coffeescript 频道内:在 /app/assets/javascripts/channels/visit.coffee
找到 - 如何设置 visit_id
以便我可以 "listen" 仅在我想要的访问时进行更改?
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: 'HOW_DO_I_SET_THIS?' },
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) ->
console.log data
push: ->
@perform 'push'
我尝试过的:
我尝试了各种变体,例如:
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: <%= @visit.id %> }
结果:
ExecJS::RuntimeError in Visits#action_cable
Showing /Users/johnsalzarulo/code/uvohealth/app/views/layouts/application.html.erb where line #9 raised:
SyntaxError: [stdin]:1:81: unexpected <
和
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: "#{ params[:id] }")
结果:
ExecJS::RuntimeError in Visits#action_cable
Showing /Users/johnsalzarulo/code/uvohealth/app/views/layouts/application.html.erb where line #9 raised:
SyntaxError: [stdin]:1:93: unexpected :
和
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: "#{ @visit.id }")
结果:
visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:4 Uncaught TypeError: Cannot read property 'id' of undefined
at visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:4
at visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:18
(anonymous) @ visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:4
(anonymous) @ visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:18
和
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: "#{ visit.id }")
结果:
visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:4 Uncaught ReferenceError: visit is not defined
at visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:4
at visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:18
(anonymous) @ visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:4
(anonymous) @ visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:18
收盘中
我尝试了很多很多组合。唯一有用的是将 <script>
扔到那个明确订阅访问的页面的视图模板中,但后来我没有得到回调的好处,而且我知道这不是"rails way"。
阅读这些文档并尝试完成这项工作已经花费了数小时。谁能阐明我在这里缺少的东西?
在 HTML 标签中设置 visit_id
,也许在布局文件的 body
标签中。
<body data-visit-id="<%= @visit.id %>">
现在从 JS 中读取它是这样的:
document.querySelector('body').dataset.visitId
您的订阅创建行将如下所示:
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: document.querySelector('body').dataset.visitId)
这里有几点需要考虑:
- 所有脚本的加载顺序。
- ruby变量的"instantiation"的具体时间,(哪里/什么时候可以访问)。
- 意识到普通的 ol' JavaScript 可以在愚蠢的 CoffeeScript 中使用。
就是说 - 这是对我有用的解决方案:
文件和支持
上述问题中使用的所有文件均未更改,但以下内容除外。要使其正常工作,您需要参考上面的文件和下面的完整堆栈文件。
我的应用程序的主模板:app/views/layouts/application.html.erb
注意 head 标签内的行 yield(:head_attributes)
<!DOCTYPE html>
<html>
<head <%= yield(:head_attributes) %> >
<title>Uvo Health</title>
<%= action_cable_meta_tag %>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body <%= yield(:body_attributes) %> >
<%= render 'layouts/navbar' unless @hide_nav %>
<%= render 'shared/flash_messages' %>
<%= yield %>
<%= yield :page_js %>
</body>
</html>
我尝试在其中使用 actioncable 的页面的视图。在我的例子中是:app/views/visits/action_cable.html.erb
- 大多数时候它可能是你的 show.html.erb
或 index.html.erb
注意 content_for
<%= content_for(:head_attributes) do %>data-visit-id="<%= @visit.id %>"<% end %>
<div class='container'>
<%= render 'visits/visit_overview' %>
</div>
然后在我的访问频道/app/assets/javascripts/channels/visit.coffee
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: document.querySelector('head').dataset.visitId },
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) ->
console.log data
push: ->
@perform 'push'
发生了什么:
- 当页面加载时,视图将
data-visit-id
的数据属性添加到页面的头部。
visit.coffee
的频道从页面头部读取该属性。
- 然后
visit.coffee
可以使用这个变量来订阅合适的频道。
其他解决方案不起作用,因为我试图以错误的方式访问内容 'order' 意思是,在变量被实例化之前加载它。希望这对其他人有帮助。这个难倒了我整整 5 个小时。
似乎几个月来,我一直在努力研究动作电缆。请帮忙。
我有一个 "Connection" - 我无法设置 identified_by :current_user
因为这个端点也需要被使用 WebSockets 的外部 API 使用。无法使用浏览器 cookie 来验证 API 端点。
文件与支持
连接:/app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
end
end
频道:/app/channels/application_cable/channel.rb
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
我有一个特定的访问渠道:/app/channels/visits_channel.rb
class VisitChannel < ApplicationCable::Channel
def subscribed
stream_from "visit_#{params[:visit_id]}"
end
end
然后我有我的 coffeescript 频道:/app/assets/javascripts/channels/visit.coffee
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: '42' },
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) ->
console.log data
push: ->
@perform 'push'
然后我的访问模型回调:/app/models/visit.rb
class Visit < ApplicationRecord
after_save :push_to_action_cable
**** detail of model removed ****
def push_to_action_cable
ActionCable.server.broadcast("visit_#{self.id}", self)
end
end
这是完美的,它每次都将对象放到控制台,并且只有 ID 为 42
的对象这是我的问题:
在 coffeescript 频道内:在 /app/assets/javascripts/channels/visit.coffee
找到 - 如何设置 visit_id
以便我可以 "listen" 仅在我想要的访问时进行更改?
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: 'HOW_DO_I_SET_THIS?' },
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) ->
console.log data
push: ->
@perform 'push'
我尝试过的:
我尝试了各种变体,例如:
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: <%= @visit.id %> }
结果:
ExecJS::RuntimeError in Visits#action_cable
Showing /Users/johnsalzarulo/code/uvohealth/app/views/layouts/application.html.erb where line #9 raised:
SyntaxError: [stdin]:1:81: unexpected <
和
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: "#{ params[:id] }")
结果:
ExecJS::RuntimeError in Visits#action_cable
Showing /Users/johnsalzarulo/code/uvohealth/app/views/layouts/application.html.erb where line #9 raised:
SyntaxError: [stdin]:1:93: unexpected :
和
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: "#{ @visit.id }")
结果:
visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:4 Uncaught TypeError: Cannot read property 'id' of undefined
at visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:4
at visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:18
(anonymous) @ visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:4
(anonymous) @ visit.self-e04de4513d06884493c48f4065f94d23255be682f915e26766c54bb9d17ef305.js?body=1:18
和
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: "#{ visit.id }")
结果:
visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:4 Uncaught ReferenceError: visit is not defined
at visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:4
at visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:18
(anonymous) @ visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:4
(anonymous) @ visit.self-b636f38376edc085c15c2cfc4d524bafc5c5163a8c136b80ba1dda12813fc0b5.js?body=1:18
收盘中
我尝试了很多很多组合。唯一有用的是将 <script>
扔到那个明确订阅访问的页面的视图模板中,但后来我没有得到回调的好处,而且我知道这不是"rails way"。
阅读这些文档并尝试完成这项工作已经花费了数小时。谁能阐明我在这里缺少的东西?
在 HTML 标签中设置 visit_id
,也许在布局文件的 body
标签中。
<body data-visit-id="<%= @visit.id %>">
现在从 JS 中读取它是这样的:
document.querySelector('body').dataset.visitId
您的订阅创建行将如下所示:
App.visit = App.cable.subscriptions.create (channel: 'VisitChannel', visit_id: document.querySelector('body').dataset.visitId)
这里有几点需要考虑:
- 所有脚本的加载顺序。
- ruby变量的"instantiation"的具体时间,(哪里/什么时候可以访问)。
- 意识到普通的 ol' JavaScript 可以在愚蠢的 CoffeeScript 中使用。
就是说 - 这是对我有用的解决方案:
文件和支持
上述问题中使用的所有文件均未更改,但以下内容除外。要使其正常工作,您需要参考上面的文件和下面的完整堆栈文件。
我的应用程序的主模板:app/views/layouts/application.html.erb
注意 head 标签内的行 yield(:head_attributes)
<!DOCTYPE html>
<html>
<head <%= yield(:head_attributes) %> >
<title>Uvo Health</title>
<%= action_cable_meta_tag %>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body <%= yield(:body_attributes) %> >
<%= render 'layouts/navbar' unless @hide_nav %>
<%= render 'shared/flash_messages' %>
<%= yield %>
<%= yield :page_js %>
</body>
</html>
我尝试在其中使用 actioncable 的页面的视图。在我的例子中是:app/views/visits/action_cable.html.erb
- 大多数时候它可能是你的 show.html.erb
或 index.html.erb
注意 content_for
<%= content_for(:head_attributes) do %>data-visit-id="<%= @visit.id %>"<% end %>
<div class='container'>
<%= render 'visits/visit_overview' %>
</div>
然后在我的访问频道/app/assets/javascripts/channels/visit.coffee
App.visit = App.cable.subscriptions.create { channel: 'VisitChannel', visit_id: document.querySelector('head').dataset.visitId },
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) ->
console.log data
push: ->
@perform 'push'
发生了什么:
- 当页面加载时,视图将
data-visit-id
的数据属性添加到页面的头部。 visit.coffee
的频道从页面头部读取该属性。- 然后
visit.coffee
可以使用这个变量来订阅合适的频道。
其他解决方案不起作用,因为我试图以错误的方式访问内容 'order' 意思是,在变量被实例化之前加载它。希望这对其他人有帮助。这个难倒了我整整 5 个小时。