javascript - 重新渲染 subview 后 Backbone 事件多次触发

标签 javascript backbone.js

我们有一个主干 View ,由一个侧边栏和几个 subview 组成。为简单起见,我们决定让侧边栏和 subview 由单个 render 函数管理。但是,click .edit 事件似乎在单击其中一个侧边栏项目后多次触发。例如,如果我从“general”开始并单击 .edit,那么 hello 会触发一次。如果我随后单击边栏上的 .profile 并再次单击 .edithello 将触发两次。有什么想法吗?

查看

events: {
  "click .general": "general",
  "click .profile": "profile",
  "click .edit": "hello",
},

general: function() {
  app.router.navigate("/account/general", {trigger: true});
},

profile: function() {
  app.router.navigate("/account/profile", {trigger: true});
},

render: function(section) {
  $(this.el).html(getHTML("#account-template", {}));
  this.$("#sidebar").html(getHTML("#account-sidebar-template", {}));
  this.$("#sidebar div").removeClass("active");
  switch (this.options.section) {
    case "profile":
      this.$("#sidebar .profile").addClass("active");
      this.$("#content").html(getHTML("#account-profile-template"));
      break;
    default:
      this.$("#sidebar .general").addClass("active");
      this.$("#content").html(getHTML("#account-general-template"));
  }
},

hello: function() {
  console.log("Hello world.");
},

路由器

account: function(section) {
  if (section) {
    var section = section.toLowerCase();
  }
  app.view = new AccountView({model: app.user, section: section});
},

解决方案

我的解决方案是将路由器更改为:

account: function(section) {
  if (section) {
    var section = section.toLowerCase();
  }
  if (app.view) {
    app.view.undelegateEvents();
  }
  app.view = new AccountView({model: app.user, section: section});
},

这暂时可行,但这会造成内存泄漏吗?

最佳答案

当我第一次开始使用 backbone 时,我遇到了完全相同的问题。正如 Peter 所说,问题在于您有多个正在创建和监听事件的 View 实例。为了解决这个问题,我在上一个主干项目中创建了这个解决方案:

/* Router view functions */
showContact:function () {
    require([
        'views/contact'
    ], $.proxy(function (ContactView) {
        this.setCurrentView(ContactView).render();
    }, this));
},
showBlog:function () {
    require([
        'views/blog'
    ], $.proxy(function (BlogView) {
        this.setCurrentView(BlogView).render();
    }, this));
},


/* Utility functions */
setCurrentView:function (view) {
    if (view != this._currentView) {
        if (this._currentView != null && this._currentView.remove != null) {
            this._currentView.remove();
        }
        this._currentView = new view();
    }
    return this._currentView;
}

如您所见,它总是删除最后一个 View 并创建一个新 View ,然后进行渲染。我还在路由器中添加了一条 require 语句,因为我不想在实际需要之前加载路由器中的所有 View 。祝你好运。

关于javascript - 重新渲染 subview 后 Backbone 事件多次触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17822518/

相关文章:

javascript - 通过 jQuery 检查是否存在具有相同选项类的任何其他选择标签的更改

javascript - 想要在鼠标悬停时更改文本

javascript - 第一次加载主干 View 时出现问题

javascript - 为什么我需要加载jquery两次

javascript - 在集合上设置属性 - backbone js

javascript - 如何保护 Chrome 应用中的某些代码?

javascript - 创建时访问 jQueryUI 对话框按钮

javascript - Backbone.js 获取 JSON 时出现问题

javascript - 隐藏 html 输入元素,直到加载 javascript

javascript - 主干集集合属性(用于url)