【问题标题】:Backbone.js - event trigger not work after rendering other viewsBackbone.js - 渲染其他视图后事件触发器不起作用
【发布时间】:2012-07-02 03:06:59
【问题描述】:

我的路由器中有一个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 });
  });
}

【问题讨论】:

    标签: events view backbone.js triggers render


    【解决方案1】:

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

    除了元素本身,所有与元素关联的绑定事件和 jQuery 数据都被移除。

    因此,Backbone 用于将事件绑定到您的 postAddView.el 的 delegate 调用将丢失。然后,当您重新添加您的postAddView.el 时,将不再附加delegate,也不会触发任何事件。注意Backbone.View 的标准remove 方法调用jQuery 的remove; jQuery 中还有一些其他的东西,就像 empty 会做类似的事情到事件处理程序。因此,杀死您的 delegate 的实际函数调用可能隐藏在其他东西的深处。

    您可以尝试手动拨打delegateEvents:

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

    或者更好的是,只需将视图扔掉,并在每次需要时创建一个新视图。您的视图对象应该非常轻量级,因此创建新视图对象应该比手动跟踪现有视图更便宜且省事。

    【讨论】:

      【解决方案2】:

      如果你真的想重用当前的 DOM 和视图,你不需要像你一样一次又一次地设置元素,你调用 .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()

      【讨论】:

        猜你喜欢
        • 2012-03-19
        • 1970-01-01
        • 1970-01-01
        • 2014-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-30
        • 1970-01-01
        相关资源
        最近更新 更多