2014-05-08 76 views
10

起初,所有的javascript绑定都运行得很好。Rails 4 + Turbolinks + JQuery Turbolinks + Coffeescript:被多次触发的事件

但是,从我导航到另一个页面的那一刻起,任何事件都会被多次触发。如果我刷新页面,一切都恢复正常。

在jquery.turbolink文档中,关于绑定$(function())块内的文档事件的there is an alert。然而,似乎默认情况下,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!" 

事情是,很明显,默认情况下,由coffeescript生成的JavaScript文件是在块内部。检查出来:

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? 我应该做不同的配置吗?

干杯。

回答

11

问题出在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。它提到了这个问题和解决方案。 (在自述文件中搜索“事件触发两次或更多次”)

0

事实证明,我已经完全改变了方法。

现在,我已经有了完全相同的环境,但我使用类来表示每个控制器的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 

现在,它就像一个魅力。 :)