2013-10-31 92 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元素。