2013-03-24 151 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