2013-03-24 59 views
2

好的,所以我在獲取事件綁定與Coffeescript和Backbone一起工作時遇到了一些困難。我有一種感覺,它與我如何初始化一切有關;我覺得事件代表團甚至沒有運行。似乎無法正確綁定Coffeescript中的Backbone事件

這裏是我的視圖代碼:

$ -> 
    class AppName.TitleView extends Backbone.View 
    template: JST['templates/title'] 
    collection: new AppName.Members 
    events: 
     "keypress #search"  : "search", 
    initialize: => 
     $('#search').keypress(@search) #doing it manually as a hack 
    search: -> 
     console.log('search handler call') 
    render: => 
     $('#app').html(@template) 
     @delegateEvents() #this doesn't seem to do anything, nor does @delegateEvents(@events) 
     @ 

其中,在編譯時,看起來是這樣的:

(function() { 
    var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 
    __hasProp = Object.prototype.hasOwnProperty, 
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 

    $(function() { 
    AppName.TitleView = (function(_super) { 

     __extends(TitleView, _super); 

     function TitleView() { 
     this.render = __bind(this.render, this); 
     this.initialize = __bind(this.initialize, this); 
     TitleView.__super__.constructor.apply(this, arguments); 
     } 

     TitleView.prototype.template = JST['templates/title']; 

     TitleView.prototype.collection = new AppName.Members; 

     TitleView.prototype.events = { 
     "keypress #search": "search", 
     }; 

     TitleView.prototype.initialize = function() { 
     return $('#search').keypress(this.search); 
     }; 


     TitleView.prototype.search = function() { 

     console.log('search handler call');); 
     }); 
     }; 

     TitleView.prototype.render = function() { 
     $('#app').html(this.template); 
     this.delegateEvents(); 
     return this; 
     }; 

     return TitleView; 

    })(Backbone.View); 
    }); 

}).call(this); 

AppName.TitleView從我的路由器拉開序幕(後者又被拉開序幕主要app.coffee)與:

$ -> 
    class AppName.Router extends Backbone.Router 
    routes: 
     ".*": "main" 

    main: -> 
     @titleView ||= new AppName.TitleView el: $('#app')[0] 
     @titleView.render() 

但是,爲了我,我無法從Backbone Events綁定到#search。我的破解(在代碼中)只是通過initialize函數中的jQuery進行綁定。

任何想法是怎麼回事?我希望這是一個簡單的錯字或錯誤的初始化。

回答

5

使用jQuery的on的委託形式,查看事件綁定到視圖的el。這意味着您在視圖的events對象必須中提到的所有內容都位於視圖的el內,否則將不會觸發事件處理程序。

默認情況下,視圖的el是一個空<div>和視圖將創建<div>當它需要和綁定事件,至<div>。你可能會注意到你的代碼中沒有使用this.elthis.$el;你的事件被正確綁定,但它們綁定到DOM中的任何東西,所以看起來事件不起作用。

兩個直接的可能性出現:

  1. 使用#app作爲視圖的el

    class AppName.TitleView extends Backbone.View 
        #... 
        el: '#app' 
        #... 
        render: => 
        @$el.html(@template) 
        @ 
    
  2. 做事的普通主幹路,並創建一個el只爲您的觀點:

    class AppName.TitleView extends Backbone.View 
        #... 
        render: => 
        @$el.html(@template) 
        @ 
    
    v = new AppName.TitleView 
    $('#app').append(v.render().el) 
    

我推薦後者,因爲它更易於管理,並且可以幫助您避免將多個視圖附加到相同的DOM元素(以及來自該元素的殭屍)。

此外,@template幾乎都是一個函數,所以你要說:

$('#app').html(@template()) 
+0

你,先生,是CoffeeScript的堆棧溢出問題的蝙蝠俠!謝謝! – CamelBlues 2013-03-24 20:55:30