2017-07-26 92 views
1

我正在Rails的一家小书店工作。用户可以为个别书籍撰写评论,并将其添加到产品页面。我想使用ActionCable将新评论添加到页面,以便它始终处于最新状态,并在为当前处于同一页面上的其他用户添加评论时显示一个小警报通知。ActionCable频道订阅不起作用,因为频道方法未执行

因此,我想根据产品的ID为每个产品设置单独的渠道。当用户打开产品页面时,她应该订阅相应的频道。

为了达到这个目的,我试图调用一个名为listen的方法,我添加到ProductChannel类中,每当通过调用JS中的App.product.perform('listen', {product_id: 1})加载新站点时。但问题是,虽然perform被调用,listen永远不会执行。我在做什么错误或误解?提前致谢!

内容javascript/channels/prouduct.coffee

内容的 channels/product_channel.rb
App.product = App.cable.subscriptions.create "ProductChannel", 
    connected:() -> 
     return 

    disconnected: -> 
     # Called when the subscription has been terminated by the server 
     return 

    received: (data) -> 
     # Called when there's incoming data on the websocket for this channel 
     console.log("there is data incoming so lets show the alert") 
     $(".alert.alert-info").show() 
     return 

    listen_to_comments: -> 
     @perform "listen", product_id: $("[data-product-id]").data("product-id") 

$(document).on 'turbolinks:load', -> 
    App.product.listen_to_comments() 
    return 

class ProductChannel < ApplicationCable::Channel 
    def subscribed 
    end 

    def unsubscribed 
    end 

    def listen(data) 
    stop_all_streams 
    stream_for data["product_id"] 
    end 
end 
+0

它可能是turbolinks,当你把App.product.listen_to_comments放入js控制台时会发生什么? – Snake

+0

它按预期返回方法。我刚刚发现,提交审阅时不规则地调用listen方法,这不是正确的时刻。我无法理解它。 – drdn5

+0

我怀疑turbolinks:负载发射多次。试穿: i = 0; $(document).on'turbolinks:load', - > console.log i ++ – Snake

回答

0

连接对象已被实例化:

module ApplicationCable 
    class Connection < ActionCable::Connection::Base 
    identified_by :current_user 

    def connect 
     self.current_user = find_verified_user 
     logger.add_tags current_user.name 
    end 

    def disconnect 
     # Any cleanup work needed when the cable connection is cut. 
    end 

    protected 
     def find_verified_user 
     if current_user = User.find_by_identity cookies.signed[:identity_id] 
      current_user 
     else 
      reject_unauthorized_connection 
     end 
     end 
    end 
end 

然后,你需要broadcast_to的@product

class ProductChannel < ApplicationCable::Channel 
    def subscribed 
    @product = Product.find(params[:product_id]) 
    end 

    def unsubscribed 
    stop_all_streams 
    end 

    def listen(data) 
    stream_for @product 
    ProductsChannel.broadcast_to(@product) 
    end 
end 
+0

非常感谢您的输入,Snake。但我确实实例化了连接对象并设置了广播。我将问题简化为@perform()方法,该方法在第一次调用时返回false,但在每次进一步调用时返回true。我为它创建了一个新问题,它更具体:https://stackoverflow.com/questions/45336276/actioncable-channel-subscription-method-perform-returns-false-on-first-call-of – drdn5