2

さて、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()

しかし、私の一生の#search間、バックボーンイベントからバインドするためのバインドを取得することはできません。initialize私のハック(コード内にあります)は、関数内のjQueryを介してバインドすることです。

何が起こっているのか分かりますか?これが単純なタイプミスまたは初期化の誤りであることを願っています。

4

1 に答える 1

5

ビューイベントはel、jQueryの委任形式を使用してビューにバインドされonます。つまり、ビューのeventsオブジェクトで言及するものはすべて、ビューの内部にある必要elがあります。そうでない場合、イベントハンドラーはトリガーされません。

デフォルトでは、ビューelは空<div>であり、ビューは必要なときにそれを作成し<div>、イベントをそのビューにバインドします<div>。コードのどこでもthis.el使用していないことに気付くかもしれません。this.$elイベントは適切にバインドされていますが、DOMに配置したものにバインドされているため、イベントが機能していないように見えます。

2つの直接的な可能性が生じます:

  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())
于 2013-03-24T20:47:30.307 に答える