模板:

<div class="view">
  <input id="todo_complete" type="checkbox" <%= completed ? 'checked="checked"' : '' %> />
  <label><%= title %></label>
  <button class="destroy"></button>
</div>
<input class="edit" value="<%= title %>" />


视图:

var TodoView = Backbone.View.extend({
  tagName: 'li',

  todoTpl: _.template($('#item-template').html()),

  events: {
    'dblclick label': 'edit',
    'keypress .edit': 'updateOnEnter',
    'blur .edit': 'close'
  },

  initialize: function() {
    console.log('Todo View initialized!');
    this.$el = $('#todo');
    console.log(this.$el);
    this.render();
  },

  render: function() {
    console.log('Todo View render started...');
    console.log(this.model.attributes);
    this.$el.html(this.todoTpl(this.model.attributes));
  },

  edit: function() {console.log('edit called!');},

  close: function() {console.log('close called!');},

  updateOnEnter: function(e) {
    console.log(e);
  }
});


页面加载时没有事件,我能够看到渲染的模板。但是,如果我双击label,在input上按键或模糊其他输入,则什么也没有发生。我希望在控制台中看到日志。我究竟做错了什么?

最佳答案

在以下情况下,您将丢失事件绑定:

this.$el = $('#todo');


您不应直接分配给$elel属性,而应调用setElement


  setElement view.setElement(element)
  
  如果您想将Backbone视图应用于另一个DOM元素,请使用setElement,它还将创建缓存的$el引用,并将视图的委托事件从旧元素移到新元素。


另外,如果您要更改视图的el,则不需要tagName属性。您也可以在创建视图时指定el

new TodoView({ el: '#todo' });
new TodoView({ el: $('#todo') });


如果您的#todo实际上是<ul><ol>,则:


单独保留tagName
通过调用el而不是调用$('#todo'),将视图的append添加到setElement


如果是这种情况,那么您的代码将更像这样:

var TodoView = Backbone.View.extend({
  tagName: 'li',
  //...
  initialize: function() {
    console.log('Todo View initialized!');
    this.render();
  },
  //...
});

// And then where you create the view...
var v = new TodoView(...);
$('#todo').append(v.el);

08-03 21:48