Backbone.js - 渲染其他视图后,事件触发器不起作用

时间:2012-07-02 03:07:00

标签: events view backbone.js triggers render

我的路由器中有addPost个功能。每次调用函数时我都不想重新创建postAddView

addPost: function () {
  var that = this;
  if (!this.postAddView) {
    this.postAddView = new PostAddView({
      model: new Post()
    });
    this.postAddView.on('back', function () {
      that.navigate('#/post/list', { trigger: true });
    });
  }

  this.elms['page-content'].html(this.postAddView.render().el);
}

这是PostAddView:

PostAddView = backbone.View.extend({
  events: {
    'click #post-add-back': 'back'
  }
  , back: function (e) {
    e.preventDefault();
    this.trigger('back');
  }
});

第一次渲染postAddView时,事件触发器运行良好。但是,在将其他视图渲染到page-content并渲染postAddView之后,事件触发器将不再触发。以下版本的addPost效果很好。

addPost: function () {
  var that = this, view;

  view = new PostAddView({
    model: new Post()
  });

  this.elms['page-content'].html(view.render().el);

  view.on('back', function () {
    delete view;
    that.navigate('#/post/list', { trigger: true });
  });
}

2 个答案:

答案 0 :(得分:2)

你正在某个地方调用jQuery的remove和那个

  

除了元素本身之外,还删除了与元素关联的所有绑定事件和jQuery数据。

因此,Backbone用于将事件绑定到postAddView.el的{​​{3}}调用将会丢失。然后,当您重新添加postAddView.el时,不再有delegate附加,也不会触发任何事件。请注意,Backbone.View的标准delegate方法调用jQuery的remove; jQuery中的一些其他内容,就像remove将对事件处理程序执行类似的操作一样。因此,杀死delegate的实际函数调用可能隐藏在其他内容中。

您可以尝试手动调用empty

this.elms['page-content'].html(this.postAddView.render().el);
this.postAddView.delegateEvents();

或者更好,只需抛开视图并在每次需要时创建一个新视图。您的视图对象应该非常轻,因此创建新视图对象应该比手动跟踪现有视图更便宜且更轻松。

答案 1 :(得分:1)

如果你真的想重用当前的DOM和View,你不需要像你一样一次又一次地设置元素,你调用.html()的所有内容都会破坏视图的DOM并再次生成和失去的事件。另外,我更喜欢在呈现视图之前在DOM中添加“el”。我将以这种方式拥有你的功能:

addPost: function () {
  if (!this.postAddView) {
    this.postAddView = new PostAddView({
      model: new Post()
    });
    this.postAddView.on('back', this.onBack);
    this.elms['page-content'].html(this.postAddView.el);
  }

  this.postAddView.render();

},

onBack : function () {
  this.navigate('#/post/list', { trigger: true });
}

我不喜欢使用局部变量来引用“this”。如果所有视图在初始化方法中都使用_.bindAll(this),您可以将事件绑定到视图中并使用它(检查我如何转换onBack)。

使用我的代码,无需手动调用this.delegateEvents()