Rails 4 + Turbolinks + JQuery Turbolinks + Coffeescript: события запускаются несколько раз

Сначала все ограниченные javascript работают довольно хорошо.

Однако, с момента перехода на другую страницу, любое событие запускается несколько раз. Если я обновляю страницу, все возвращается к норме.

В документах jquery.turbolink появляется предупреждение о привязке событий документа внутри блока $(function()). Однако похоже, что файл coffescript работает по умолчанию. Итак, что мне делать?

Это моя среда:

Gemfile:

gem 'turbolinks'
gem 'jquery-turbolinks'

application.js

//= require jquery
//= require jquery.turbolinks
//..app js
//= require turbolinks

application.html.erb

<html>
  <head>
    <meta charset="utf-8">
    <title><%= t 'brand' %> </title>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= yield :head %>
    <%= csrf_meta_tags %>
    <meta name="description" content="<%= yield :page_description %>">
    <meta name="keywords" content="<%= yield :page_keywords %>">
  </head>

controller.js.coffee

$(document).ready ->    
  $(document).on 'click', '.addition .label i', (e) ->
    console.log ".addition .label i 'click' fired!"

Дело в том, что, по-видимому, файл javascript, созданный coffeescript IS внутри блока по умолчанию. Проверьте это:

controller.js(сгенерированный coffeescript)

function() {
  $(document).ready(function() {
    $(document).on('click', '.addition .label i', function(e) {
      console.log(".addition .label i 'click' fired!");
    });
...

Итак, что мне делать, чтобы правильно использовать coffeescript + JQuery Turbolinks? Должен ли я сделать другую конфигурацию?

Приветствия.

Ответ 1

Проблема в файле controller.js.coffee.

Вы написали это:

$(document).ready ->    
  $(document).on 'click', '.addition .label i', (e) ->
    console.log ".addition .label i 'click' fired!"

Но поскольку вы используете jQuery Turbolinks, вам нужно переместить обработчики событий за пределы функции $(document).ready:

$(document).ready ->
  # Other code can go here, but not binding event handlers
$(document).on 'click', '.addition .label i', (e) ->
  console.log ".addition .label i 'click' fired!"

Взгляните на jQuery Turbolinks README. Он упоминает эту проблему и решение. (Поиск в readme для "События, стреляющие дважды или более".)

Ответ 2

Ну, оказалось, что я полностью изменил подход.

Теперь у меня есть точно такая же среда, но я использую классы для представления javascript для каждого контроллера. Вот один пример:

foo.js.coffee:

window.App or= {}

class App.Foo
  constructor: ->
    @$foo_container = $('.foo')
    @bind()

  bind: ->
    console.log 'App.Foo.bind has been fired!'
    @$foo_container.on 'click', '.label i', @foo_clicked

  foo_clicked: (e) =>
    console.log 'App.Foo.foo_clicked has been fired!'
    alert '.label i has been clicked!'

create_foo = ->
  window.app.foo = new App.Foo()
  console.log 'App.Foo has been created!'

$(document).ready create_foo

Теперь это работает как шарм.:)