簡體   English   中英

重新渲染子視圖后,骨干事件會多次觸發

[英]Backbone events are firing multiple times after re-rendering sub-views

我們有一個由側邊欄和幾個子視圖組成的Backbone視圖。 為簡單起見,我們決定讓側邊欄和子視圖由單個render功能控制。 但是, click .edit其中一個側邊欄項后, click .edit事件似乎會多次觸發。 例如,如果我從“general”開始並單擊.edit ,那么hello會觸發一次。 如果我再單擊.profile的側邊欄,點擊.edit再次, hello閃光兩次。 有任何想法嗎?

視圖

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

這現在有效,但這會造成內存泄漏嗎?

當我第一次開始使用骨干時,我遇到了完全相同的問題。 就像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;
}

正如您所看到的,它總是刪除最后一個視圖並創建一個新視圖然后呈現。 我還在路由器中添加了一個require語句,因為我不想在路由器中加載所有視圖,直到實際需要它們為止。 祝好運。

聽起來您正在將多個視圖實例附加到同一個DOM元素,並且它們都響應事件。 您是在每次導航時創建新視圖而不刪除上一個視圖嗎?

我有一個動態視圖,根據路由器參數在同一個元素(大約12個)內呈現不同的模板。 現在,視圖呈現的容器在view.render()中定義,如“el:'#some-container'”。 當然,我必須刪除視圖,如果它存在,在創建一個新的或相同的,以防止僵屍和s#!t。 提醒一下,調用view.remove()實際上會從DOM中刪除“#some-container”,這意味着視圖無法呈現,除了第一次。 現在,有許多方法可以防止這種情況發生。 只是想我應該分享以防任何人需要節省幾個小時的研究。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM