4

私は自分のapplication.html.hamlにいくつかのユーザー属性に応じて、特定のチャンネルにユーザーをサブスクライブするかどうかを決定するコードを持っています。Railsアクションケーブルとターボリンク:複数のバインディングを避ける

私は体内にこのコードを置いているので、別のページにリダイレクトされるリンクをクリックすると、古い接続を維持するのではなくユーザーが再度購読するので、メソッドがあります複数回実行されます。

これはapplication.html.hamlで私のコードです:

%html 
    %head 
    -# other stuff 
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload' 
    %body 
    -# other stuff 

    - if current_user.is_admin? 
     :coffee 
     MyApp.AdminNotifications.init() 

資産/ JavaScriptの/通知/ admin_notifications.js.coffee

window.MyApp.AdminNotifications = class AdminNotifications 
    @init: -> 
    App.cable.subscriptions.create "ProductsChannel", 
     received: (data) -> 
     console.log 'Data Received' # This is being executed multiple times 

ページがロードされた最初の時間、私は放送時にメッセージをそのチャンネルに送信すると、コンソールは「データ受信」を1回だけログに記録します。 リンクをクリックして別のページにリダイレクトすると、そのチャンネルに新しいメッセージがブロードキャストされ、コンソールに「データ受信済み」が2回記録されます。そして、これまでのように...

実際に

、私はクロームのコンソール上で実行すると:それは私がリンクをクリックして得たたびに一度(同じチャネルに複数のサブスクリプションを返し

App.cable.subscriptions.subscriptions 

別のページにリダイレクトされます)。

注:これは正常に機能しているため、この記事に追加していないアクションケーブルの設定があります。

どうすれば避けることができますか?何か案は?

答えて

0

あなただけのクラスが初期化されているフラグにクラス属性を追加する必要があるかもしれませんので、あなただけの、MyApp.AdminNotificationsの単一のインスタンスをしたいように見えます自分のサブスクリプションを管理するAction Cable APIをラップしたい一般的なルールとして


Turbolinksで作業する場合、(参照:https://github.com/rails/rails/pull/23012#issue-125970208)をごapplication.jsファイルではなく、インラインスクリプトで、できるだけ多くのものが含まれることが好ましいです。条件付きで実行できるようにインラインスクリプトを使用していると思います(if current_user.is_admin?)。一般的なアプローチは、ので、あなたの頭の中で、このデータを伝えるためにメタタグを使用することです:

<meta name="current-user-is-admin" content="true"> 

次にあなたが持っている可能性があり:

window.MyApp.User = class User 
    constructor: -> 
    @isAdmin = @getMeta('current-user-is-admin') == 'true' 

    getMeta: (name) -> 
    meta = document.querySelector("meta[name=#{name}]") 
    meta.getAttribute('content') if meta 

そして最後に、レイアウトからAdminNotifications初期化コードを削除することが含まこれはあなたのアプリケーションのどこかにあります。

document.addEventListener('turbolinks:load', -> 
    window.MyApp.currentUser = new window.MyApp.User 
    window.MyApp.AdminNotifications.init() if window.MyApp.currentUser.isAdmin 
) 
+0

賞金ありがとう!問題を解決するためにこの回答が見つかった場合は、「受け入れ済み」と記入してください。再度、感謝します :) –

0

体ではなく頭で書くのはどうですか? イベントがターボリンクで複数回登録されている可能性があります。将来的には

window.MyApp.AdminNotifications = class AdminNotifications 
    @init: -> 
    unless @initialized 
     App.cable.subscriptions.create "ProductsChannel", 
     received: (data) -> 
      console.log 'Data Received' 
     @initialized = true 

あなたは可能性があります

%html 
    %head 
    -# other stuff 
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload' 

    - if current_user.is_admin? 
     :coffee 
     MyApp.AdminNotifications.init() 

    %body 
    -# other stuff 
関連する問題