2014-05-08 49 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 

現在,它就像一個魅力。 :)