Ruby on Rails 7 Action Cable

3

我已经从Rails 6升级到7,现在我的Action Cable频道不再监听了。我确定这是一个愚蠢的错误,但我无论如何都找不出问题所在。

app/javascript/channels/consumer.js

import { createConsumer } from "@rails/actioncable"

export default createConsumer()

app/javascript/channels/settings_channel.js

import consumer from "./consumer"

consumer.subscriptions.create({ channel: "SettingsChannel" })

document.addEventListener('turbo:load', () => {
  //console.log(attendance_id);
  
  consumer.subscriptions.create({ channel: "SettingsChannel"}, {
    connected() {
      console.log("connected to settings channel ");
    },

    disconnected() {
      // Called when the subscription has been terminated by the server
    },

    received(data) {
      console.log("settings channel data:");
      console.log(data);

      if(data.tab){
        //clear other selected tabs first then highlight selected ones.

        const actions_tab = document.getElementById('actions-tab');
        if(actions_tab){
          actions_tab.classList.remove('settings-active-tab','settings-inactive-tab');
          if(data.tab == 'actions'){
            actions_tab.classList.add('settings-active-tab');
          }else{
            actions_tab.classList.add('settings-inactive-tab');
          }
        }
        const committees_tab = document.getElementById('committees-tab');
        if(committees_tab){
          committees_tab.classList.remove('settings-active-tab','settings-inactive-tab');
          if(data.tab == 'committees'){
            committees_tab.classList.add('settings-active-tab');
          }else{
            committees_tab.classList.add('settings-inactive-tab');
          }
        }
        const members_tab = document.getElementById('members-tab');
        if(members_tab){
          members_tab.classList.remove('settings-active-tab','settings-inactive-tab');
          if(data.tab == 'members'){
            members_tab.classList.add('settings-active-tab');
          }else{
            members_tab.classList.add('settings-inactive-tab');
          }
        }
        const motions_tab = document.getElementById('motions-tab');
        if(motions_tab){
          motions_tab.classList.remove('settings-active-tab','settings-inactive-tab');
          if(data.tab == 'motions'){
            motions_tab.classList.add('settings-active-tab');
          }else{
            motions_tab.classList.add('settings-inactive-tab');
          }
        }
        const session_tab = document.getElementById('session-tab');
        if(session_tab){
          session_tab.classList.remove('settings-active-tab','settings-inactive-tab');
          if(data.tab == 'session'){
            session_tab.classList.add('settings-active-tab');
          }else{
            session_tab.classList.add('settings-inactive-tab');
          }
        }
        const system_tab = document.getElementById('system-tab');
        if(system_tab){
          system_tab.classList.remove('settings-active-tab','settings-inactive-tab');
          if(data.tab == 'system'){
            system_tab.classList.add('settings-active-tab');
          }else{
            system_tab.classList.add('settings-inactive-tab');
          }
        }
      }

//end of inserted code for data received
    }
  });

})

app/javacript/application.js

import "@hotwired/turbo-rails"
//below is not supported yet
//import "@hotwired/stimulus-importmap-autoloader"
import "./controllers"
import "@rails/actioncable"   
import "@rails/activestorage" 
import "./channels"

import Rails from "@rails/ujs"
window.Rails = Rails;
if(Rails.fire(document, "rails:attachBindings")){
  Rails.start();
}

app/config/importmap.rb

# Pin npm packages by running ./bin/importmap

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
#pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
# Use libraries available via the asset pipeline (locally or via gems). # Rails 7.0 required
pin "@rails/actioncable", to: "actioncable.esm.js"      
pin "@rails/activestorage", to: "activestorage.esm.js" 

谢谢提前提供的任何建议!在Rails 6中,我已经成功地使用了turbolinks :-/


我认为这与我的频道未能正确加载有关,因为我在application.js中放置了document.addEventListener('turbo:load',() =>{console.log("turbo!")}),并且它写入了控制台... - epurdy
1个回答

4

问题已解决!

我的问题出在 channels/index.js 文件中。

默认情况下,Rails 7 在 channels/index.js 中提供以下代码:

const channels = require.context('.', true, /_channel\.js$/)
channels.keys().forEach(channels)

这段代码旨在自动导入所有 *_channel.js 文件。问题是目前 Stimulus 还不支持此功能(对于通道和控制器)...请参见此线程:https://github.com/hotwired/stimulus-rails/issues/73

因此,我的解决方案是在自动加载被支持之前手动加载它们。

以下是 channels/index.js 中的新代码:

import "./settings_channel"
import "./vote_channel"
import "./member_vote_channel"
import "./attendance_channel"

对我来说,将频道添加到路由很有效。例如:import "./channel/settings_channel" - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接