Das*_*kus 3 ruby-on-rails ruby-on-rails-5 actioncable
在我的项目中,我有一个模型categories,它有一个详细视图(显示).该视图包含应使用actioncable实时更新的数据.视图的内容/数据对于理解问题并不重要.
一个标准的设置,我只有一个类别与硬编码ID完美,但现在我想使它动态和页面特定,所以我不需要打开100个订阅,我mabye甚至不需要,如果我是不在类别详细信息页面上.
第一个问题:如何仅为当前页面/类别创建连接?
第二个问题:我如何获得当前类别的ID?
App.cable.subscriptions.create { channel: "RankingChannel", category_id: HOW_DO_I_GET_THIS}
Run Code Online (Sandbox Code Playgroud)
我发现的唯一的事情就是这个,但它不起作用:https: //stackoverflow.com/a/36529282/5724835
小智 6
通道似乎不是特定于页面的(就像控制器不是特定于页面的那样),但是您可以调整通道的范围(正如您尝试的那样),以便订阅仅接收给定类别的消息.
您可以通过在布局文件的头部放置这样的内容,有选择地在页面上包含通道的js文件:
<%= javascript_include_tag 'channels/'+params[:controller] %>
Run Code Online (Sandbox Code Playgroud)
而不是//= require_tree ./channels在你的cables.js文件中.
但这样做的缺点是要求您在config\initializers\assets.rb初始化程序中的预编译数组中包含js文件并重新启动服务器:
Rails.application.config.assets.precompile += %w( channels/categories.js )
Run Code Online (Sandbox Code Playgroud)
通道定义是您使用stream_for模型对流进行范围调整的位置,这使得连接ID唯一,例如,categories:Z2lkOi8vcmFpbHMtc3RaaaRlci9Vc2VyLzI而不仅仅是categories.
class RankingChannel < ApplicationCable::Channel
def subscribed
category = Category.find(params[:category_id])
stream_for category
end
...
end
Run Code Online (Sandbox Code Playgroud)
您将category_id客户端页面发送到服务器.在这里,我们通过DOM中元素的data-category-id属性#category(使用jQuery语法,但可以很容易地转换为直接js)来完成它.
$( function() {
App.categories = App.cable.subscriptions.create(
{
channel: "RankingChannel",
category_id: $("#category").data('category-id')
},{
received: function(data) {
...
}
}
);
});
Run Code Online (Sandbox Code Playgroud)
因此,在您的视图中,您需要在生成页面时包含类别ID:
<div id="category" data-category-id="<%= @category.id %>">
<div class="title">My Category</div>
...
</div>
Run Code Online (Sandbox Code Playgroud)
好吧,对于 Rails 6,我解决了类似于上面 @YaEvan 的答案。
*_channel.js文件设置了一个条件:import consumer from "./consumer"
document.addEventListener('turbolinks:load', function() {
// Because I was going to work with this element anyway, I used it to make the condition.
var body = document.getElementById("news_body");
if(body) {
consumer.subscriptions.create("NewsChannel", {
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) {
// Called when there's incoming data on the websocket for this channel
}
});
}
});
Run Code Online (Sandbox Code Playgroud)
这是一个变通办法。我没有找到正确方法的答案。所以如果你发现了,请告诉我!
| 归档时间: |
|
| 查看次数: |
1812 次 |
| 最近记录: |