2013-03-24 2 views
2

Итак, у меня довольно сложно получить привязку к событиям для работы с Coffeescript и Backbone. Я чувствую, что это связано с тем, как я все инициализирую; Я чувствую, что делегирование событий даже не выполняется.Невозможно правильно привязать базовые события в Coffeescript

Вот мой взгляд код:

$ -> 
    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() 

Но для li я не могу получить привязку к #search из базовых событий для привязки. Мой взлом (который находится в коде) - это просто привязка через jQuery в функции initialize.

Любая идея, что происходит? Я надеюсь, что это простая опечатка или неудачная инициализация.

ответ

5

Просмотреть события привязаны к виду el, используя форму делегирования jQuery's on. Это означает, что все, что вы упоминаете в объекте events вида , должно быть в представлении el, иначе обработчики событий не будут запущены.

По умолчанию, вид-х el является пустым <div> и вид создаст что <div>, когда это необходимо и связать события с этой <div>. Вы можете заметить, что вы не используете this.el или this.$el в любом месте вашего кода; ваши события связаны должным образом, но они привязаны ко всему, что вы помещаете в DOM, и поэтому похоже, что события не работают.

Два непосредственной возможность возникает:

  1. Использование #app в качестве функции представление el:

    class AppName.TitleView extends Backbone.View 
        #... 
        el: '#app' 
        #... 
        render: => 
        @$el.html(@template) 
        @ 
    
  2. ли вещам обычного Backbone путь и создать 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

Смежные вопросы