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
Теперь это работает как шарм.:)