似乎无法在Coffeescript中正确绑定Backbone事件

Cam*_*ues 2 event-binding coffeescript backbone.js backbone-events

好的,所以我在使用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)
      @
Run Code Online (Sandbox Code Playgroud)

在编译时,它看起来像这样:

(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);
Run Code Online (Sandbox Code Playgroud)

AppName.TitleView从我的路由器(主要由主要开始app.coffee)开始:

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

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

但是对于我的生活,我无法#search从Backbone Events获得绑定绑定.我的hack(在代码中)只是通过jQuery在initialize函数中绑定.

知道发生了什么事吗?我希望这是一个简单的拼写错误或初始化错误.

mu *_*ort 5

el使用jQuery的委托形式将视图事件绑定到视图on.这意味着您在视图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)
        @
    
    Run Code Online (Sandbox Code Playgroud)
  2. 以通常的Backbone方式做事并el为您的视图创建一个公正的:

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

我推荐后者,因为它更容易管理,并将帮助您避免将多个视图附加到相同的DOM元素(以及倾向于来自它的僵尸).

此外,@template几乎总是一个函数所以你想说:

$('#app').html(@template())
Run Code Online (Sandbox Code Playgroud)