2013-10-31 93 views
0

我在Backbone中有兩個視圖。註冊視圖和登錄視圖。如何僅將主動視圖中的事件委託給主幹?

登錄查看

define(['text!templates/login.html'], function(loginTemplate) { 
var loginView = Backbone.View.extend({ 
    el: $('#content'), 

    events: { 
     "submit form": "login" 
    }, 

    login: function(e) { 
     e.preventDefault(); 
     $.post('/user/login', { 
       email: $('input.login-email').val(), 
       password: $('input.login-password').val() 
      }, function(data) { 
       console.log(data); 
      }).error(function(){ 
       $("#error").text('Unable to login.'); 
       $("#error").slideDown(); 
      }); 
    }, 

    render: function() { 
     this.$el.html(loginTemplate); 
    } 
}); 

return new loginView; 
}); 

註冊視圖

define(['text!templates/register.html'], function(registerTemplate) { 
var registerView = Backbone.View.extend({ 
    el: $('#content'), 

    events: { 
     "submit form": "register" 
    }, 

    register: function(e) { 
     e.preventDefault(); 
     $.post('/user/register', { 
      emailaddress: $("input.email").val(), 
      password: $("input.password").val() 
     }, function(data, textStatus, jqXHR) { 
      console.log(data); 
     }); 
    }, 

    render: function() { 
     this.$el.html(registerTemplate); 
     this.delegateEvents(); 
    } 
}); 

return new registerView; 
}); 

而且我在另一個開關之前undelegate從currentView的事件。但骨幹視圖模型在其構造函數中調用了delegateEvent()函數。因此,當我在瀏覽器中打開頁面並獲取登錄視圖並要提交表單時,有兩個請求,因爲來自兩個視圖的事件都已委派。我可以阻止構造函數中的delegateEvent函數嗎?我知道,我可以使用ID,但我不喜歡'混亂',我只想要來自活動視圖的事件。

非常感謝。

編輯:這裏是我的路由器,也許它是我的「bug」的來源。

define(['views/register', 'views/login'], function(RegisterView, LoginView) { 
var TestRouter = Backbone.Router.extend({ 
    currentView: null, 
    routes: { 
     "login": "login", 
     "register": "register" 
    }, 

    changeView: function(view) { 
     if (this.currentView != null) { 
      this.currentView.undelegateEvents(); 
     } 
     this.currentView = view; 
     this.currentView.render(); 
    }, 

    login: function() { 
     this.changeView(LoginView); 
    }, 

    register: function() { 
     this.changeView(RegisterView); 
    } 
}); 

return new TestRouter; 
}); 

回答

2

這裏的問題是,你聲明手動el屬性(el: $('#content'))。

在乾淨的代碼中,你不想這樣做。相反,您想管理視圖在路由器或父視圖中動態插入的位置。像這樣:

var view = new registerView(); 
view.render().$el.appendTo("#content"); 

它的佈局與觀點分開,讓您的代碼的維護,而不是落在你這裏的問題是非常重要的。

+0

是的,這是一個很好的建議。但是,爲什麼這會在構建意見時影響事件的委派?無論如何,這些意見會在靴帶上建成,不是嗎? – noeden

+0

是的,但代表團將在其內部包裝器「el」(這是特定於上下文)而不是'#content'(這是頁面的通用)發生。 –

+0

請注意,通常,僅在需要時構建視圖才更好。無需緩存它們以供稍後重新使用。只需要垃圾箱並在需要時重新創建,您的代碼將更容易維護,並且性能下降通常是看不到的。 –

0

我的問題的解決方案是:

當你不以每依賴注入他們建立的所有意見,但他們並沒有建造和委託的werent他們的活動。

變化

return new registerView; 

return registerView; 
在你看來

。請注意Simon Boudrias的評論,並且不要在其中聲明views元素。