在Backbone应用程序中触发输入字段事件时,第一个视图会从第二个视图中不期望地呈现?

时间:2014-10-18 23:39:54

标签: javascript backbone.js

我每个都有一个模型和一个模板以及一个表单模型实例的视图,用于从各自的模板中呈现它们。可以从两个视图访问表单模型实例以呈现其模板。需要在每个键入的字符上更新此表单模型实例,并使用此表单模型实例设置两个视图的当前视图的模型。为此,我在两个视图中的keyup元素上都有一个input事件,它具有不同数量的输入视图。第二个视图具有所有相同的typed,named,id,input字段,第一个视图和一些不同的视图。

当我在具有更多输入字段的第二个视图上并单击并在输入字段中输入两个视图中的字符时,第一个视图呈现。在路由到另一个视图之前从其中一个视图调用this.unbind()不起作用。

这是什么原因?完成后我没有事件来渲染它。 mainrouter:

    define([
    'jquery',
    'ratchet',
    'underscore',
    'backbone',

    'forms/formsdatamodel',
    'login/loginview',
    'register/registerview',

    'home/homeview',
    ],
    function($, Ratchet, _, Backbone, FormsDataModelInst, LoginView, RegisterView, HomeView){
        var MainRouter = Backbone.Router.extend({
            routes: {
                "": "render_home",              
                "login": "render_login",
                "register": "render_register"
            },
            initialize: function(){
                this.model = FormsDataModelInst;
                this.listenTo( this.model, 'change', this.render_home );//this solved render_home problem.
            },
            render_home: function(){
                if( this.model.get('loginp') == true ){ //show you app view for logged in users!
                    this.homeView = new HomeView();
                    this.homeView.render();
                }
                else { //not logged in!
                    Backbone.history.navigate("/login", {trigger:true});
                }
            },
            render_login: function(){ //display your login view
                this.loginView = new LoginView;
                //this.loginView.delegateEvents();
                this.loginView.render();
            },
            render_register: function(){ //display your register view
                this.registerView = new RegisterView;
                //this.registerView.delegateEvents();
                this.registerView.render();
            },
        });

        return MainRouter;
});

loginview:

    define([
    'jquery',
    'ratchet',
    'underscore',
    'backbone',

    'login/loginmodel',
    'text!login/logintemplate.html',

    'forms/formsdatamodel',

    ],
    function($, Ratchet, _, Backbone, LoginModel, LoginTemplate, FormsDataModelInst){
        var LoginView = Backbone.View.extend({

            el: $('body'),

            initialize: function(){
                this.model = new LoginModel();
            },

            template: _.template( LoginTemplate ),

            render: function(){ //display your login view
                this.$el.html( this.template( FormsDataModelInst.attributes ) );
            },
            events: {
                'keyup input#username' : 'updateModel',
                'click #loginbutton' : 'login',
                'click #renderregisterbutton' : 'render_register',
            },
            updateModel: function(e){
                e.preventDefault();
                var elm = e.target;
                FormsDataModelInst.set( elm.id, $( elm ).val() );
                this.model.set( FormsDataModelInst );

                console.log( "1-FormsDataModelInst:" + JSON.stringify( FormsDataModelInst.attributes ) );
                console.log( "2-this.model.set(...):" + JSON.stringify(this.model.attributes) );
            },
            login: function(e){
                e.preventDefault();
                this.model.save();

                console.log( "3-this.model.save():" + JSON.stringify(this.model.attributes) );
            },
            render_register: function(e){
                e.preventDefault();
                this.undelegateEvents();
                Backbone.history.navigate("/register", {trigger:true});
            },
        });

        return LoginView;
});

registerview:

    define([
    'jquery',
    'ratchet',
    'underscore',
    'backbone',

    'register/registermodel',
    'text!register/registertemplate.html',

    'forms/formsdatamodel',
    ],
    function($, Ratchet, _, Backbone, RegisterModel, RegisterTemplate, FormsDataModelInst){
        var RegisterView = Backbone.View.extend({

            el: $('body'),

            initialize: function(){
                this.model = new RegisterModel();
            },

            template: _.template( RegisterTemplate ),

            render: function(){ //display your login view
                this.$el.html( this.template( FormsDataModelInst.attributes ) );
            },
            events: {
                'keyup input#username' : 'updateModel',
                'keyup input#phone' : 'updateModel',
                'keyup input#email' : 'updateModel',

                'click #registerbutton' : 'register',
                'click #renderloginbutton' : 'render_login',
            },
            updateModel: function(e){
                e.preventDefault();
                var elm = e.target;
                FormsDataModelInst.set( elm.id, $( elm ).val() );
                this.model.set( FormsDataModelInst );

                console.log( "FormsDataModel:" + JSON.stringify( FormsDataModelInst ) );
                console.log( "this.model.set(...):" + JSON.stringify(this.model.attributes) );
            },
            login: function(e){
                e.preventDefault();
                this.model.save();

                console.log( "this.model.save():" + JSON.stringify(this.model) );
            },
            render_login: function(e){
                e.preventDefault();
                this.undelegateEvents();
                Backbone.history.navigate("/login", {trigger:true});
            },
        });

        return RegisterView;
});

2 个答案:

答案 0 :(得分:1)

当您实例化View时,您在el的{​​{1}}上设置了事件绑定。如果不同的View也使用相同的View,则无关紧要;只要第一个inputs仍在其事件处理器周围,处理程序将继续监听并响应事件。

您尝试拨打View时有正确的想法......除了this.unbind()没有View方法。但他们有一个unbind方法,我认为这是你正在寻找的方法。

答案 1 :(得分:0)

在mainRouter中,监听器:

this.listenTo( this.formsDataModelInst, 'change', this.render_home );

导致在loginview中输入时出现registerview不正确的问题。因为在registerview keyup上绑定了updateModelschange绑定了registermodelformsDataModelInst。此change会触发上述routeloginview并将其呈现的书面事件。

loginp formsDataModelInst的{​​{1}}属性时,需要使用上方监听器,以确定要在change mainRouter中实现哪个视图,但不是render在其他属性中,例如在表单上的change事件中更新的属性。

将其更改为:

keyup