骨干事件重新呈现子视图烧制后多次 [英] Backbone events are firing multiple times after re-rendering sub-views

查看:88
本文介绍了骨干事件重新呈现子视图烧制后多次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有由侧边栏和多个子视图的单一视图骨干。为简单起见,我们决定拥有侧栏,和子视图由一个单一的渲染管辖功能。但是,点击.edit 事件似乎点击侧边栏项目之一后进行射击多次。例如,如果我开始了对一般,然后点击 .edit ,那么你好触发一次。如果我再点击 .profile文件在侧栏上,点击 .edit 再次你好触发两次。任何想法?

We have a single Backbone view comprised of a sidebar and several sub-views. For simplicity, we've decided to have the sidebar and sub-views governed by a single render function. However, the click .edit event seems to be firing multiple times after clicking on one of the sidebar items. For example, if I start out on "general" and click .edit, then hello fires once. If I then click .profile on the sidebar and click .edit again, hello fires twice. Any ideas?

查看

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});
},

解决方案

我的解决办法是改变路由器这样的:

My solution was to change the router to this:

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

这适用于现在,但将在创建内存泄漏?

This works for now, but will this create a memory leak?

推荐答案

我有完全一样的问题,当我使用骨干第一次开始。就像彼得说,问题是,你必须要创建的视图的多个实例,并侦听该事件。为了解决这个问题,我在上次骨干工程创造了这个解决方案:

I had exactly the same problem when I first started using backbone. Like Peter says, the problem is that you have more than one instance of the View being created and listening for the event. To solve this, I created this solution in my last backbone project:

/* 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;
}

正如你所看到的,它总是删除最后一个视图,并创建一个新的,然后呈现。我还添加了需要在路由器的语句,因为我不希望有,直到他们真正需要加载所有意见路由器。祝你好运。

As you can see, it's always removing the last view and creating a new one, which then renders. I also add a require statement in the router because I don't want to have to load all views in the router until they are actually needed. Good luck.

这篇关于骨干事件重新呈现子视图烧制后多次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆