如何仅委托骨干网中活动视图中的事件?

时间:2013-10-31 14:17:01

标签: backbone.js backbone-views backbone-events

我在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;
});

我在切换到另一个之前从当前视图中取消了这些事件。但是主干视图模型在其构造函数中调用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 个答案:

答案 0 :(得分:2)

此处的问题是您手动声明el属性(el: $('#content'))。

在干净的代码中,您不想这样做。相反,您希望管理视图在路由器或父视图中动态插入的位置。像这样:

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

将布局与视图分开是非常重要的,这样可以保持代码的可维护性,而不会影响您的问题。

答案 1 :(得分:0)

我的问题的解决方案是:

当你没有构建所有视图时,每个依赖项注入它们,它们没有被构造,也没有委派他们的事件。

更改

return new registerView;

return registerView;
在你看来

。请注意Simon Boudrias的评论,不要在其中声明views元素。