【问题标题】:Call JavaScript constructor method from different file - Rails从不同的文件调用 JavaScript 构造函数方法 - Rails
【发布时间】:2017-12-06 18:02:14
【问题描述】:

我正在使用Unobtrusive JavaScript solution for polling in a Rails application,这似乎是一个很好的解决方案,尽管我无法从.js.erb 视图调用.stop() 方法。我希望能够在为通过轮询刷新的项目之一打开内联编辑表单时停止轮询。我从edit.js.erb视图中调用.stop(),但它一直在轮询......

unobtrusive_poller.coffee:

class Poller

  constructor: (@div) ->

  interval: ->
    $(@div).data("interval") ? 3000

  url: ->
    $(@div).data("url")

  start: ->
    console.log "Starting polling"
    @intervalId = setInterval(@request, @interval())

  request: =>
    # console.log "Interval: #{@interval()}"
    # console.log "URL: #{@url()}"
    console.log "Polling"
    $.ajax(
      url: @url(),
      dataType: "script").fail (data) =>
      console.log "Poll failed!" # + JSON.stringify(data)
      return

  stop: ->
    console.log "Stopping polling"
    clearInterval(@intervalId)

$(document).on 'turbolinks:load', ->
  $("div[data-poll='true']").each (i, div) ->
    console.log "DIV: " + div
    new Poller(div).start()

edit.js.erb:

// Pause polling while edit form is open
console.log($('div#messages[data-poll='true']'));
new Poller($('div#messages[data-poll='true']')).stop();

// $("div[data-poll='true']").each(function(i, div) {
//   console.log("DIV: " + div);
//   return new Poller(div).stop();
// });

...

据我了解,问题是 @intervalId 未定义。

这是在正确的轨道上吗?

任何关于如何完成这项工作的建议将不胜感激。

谢谢!

【问题讨论】:

    标签: javascript ruby-on-rails ajax coffeescript erb


    【解决方案1】:

    您需要存储正在初始化轮询事件的每个div 的对象。您每次都在创建新对象,但不会将其存储在任何地方。您需要将其存储在某个地方,以便稍后在创建的对象上调用 stop。

    更新:将 Id 存储在 Hash 中

    此代码创建一个哈希图来存储您绑定的所有投票事件

    window.pollHash = {}
    
    $(document).on 'turbolinks:load', ->
      $("div[data-poll='true']").each (i, div) ->
        console.log "DIV: " + div
        id = $(div).attr("id")
        pollObject = new Poller(div)
        pollObject.start()
        window.pollHash[id] = pollObject
    

    在 edit.js.erb 中,您再次使用 new 运算符创建新对象。您应该像上面那样使用已经存储的对象,然后调用 stop 方法,如下所示。

    targetDiv = $('div#messages[data-poll='true']')
    //Not sure about your target condition, replace 
    // above selector as your target as per your need.
    targetId = $(targetDiv).attr("id")
    window.pollHash[targetId].stop()
    

    希望对你有帮助!

    【讨论】:

    • 感谢您的建议!这是一个很好的建议,但我不想遍历所有已启动的 Poller 对象并停止它们。我只想能够阻止一个特定的Poller。您对如何定位数组中的特定Poller 有什么建议吗?再次感谢!
    • 如果你可以为每个 div 添加一个特定的 ID。这是可能的。到那时它很难停止目标 div。即使您可以附加一个虚拟的唯一类,它也可以工作。让我知道这是否可能,我会更新我的答案。
    • 我已经更新了代码,看看。它将存储 id 的所有哈希,然后在特定目标 div 上触发停止。如果这就是你想要的。
    • 这越来越近了!我不需要更改.stop() 方法使其不引用@intervalId吗?
    • 好吧,间隔 id 是 setInterval 返回的东西。当您创建一个时,它是独一无二的。因此,当您想要停止该特定对象的间隔时,它是必需的。该代码是完美的,因为它将intervalId 绑定到对象并且应该保持原样。您无法跟踪为哪个 div 生成了哪个 Id,除非您为其创建哈希映射。但是,如果您手动管理intervalIds,那将破坏stop 方法的全部目的。希望这是有道理的!
    猜你喜欢
    • 2013-05-08
    • 2018-08-20
    • 2015-10-10
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 2012-09-16
    • 2016-05-31
    • 1970-01-01
    相关资源
    最近更新 更多