Reputation: 3070
I have views each with a model and a template and one form model instance to render them from their respective templates. Form model instance is accessible from both view to render their templates. It is needed to update this form model instance on every character typed, and set the model of the current view of the two views with this form model instance. For this I have an keyup
event on input
elements in both views, which has different number of input views. Second view has all the same typed, named, id, input
fields with the first view and some different ones.
When I am on the second view with more input fields and click and type a character in the input field both views have, the first view renders. Calling this.unbind()
from one of the view before it routes to the other view did not work.
What is the reason for this? I do not have an event to render it when this is done. 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;
});
Upvotes: 0
Views: 42
Reputation: 3070
In mainRouter the listener:
this.listenTo( this.formsDataModelInst, 'change', this.render_home );
causes the problem of rendering loginview
undesirebly on typing in registerview
. Because on registerview
keyup
is bound to updateModels
and this change
s both registermodel
and formsDataModelInst
. this change
triggers above written event which route
s to the loginview
and renders it.
Above listener is needed when loginp
property of the formsDataModelInst
change
s, to decide which View to render as implemented in mainRouter
render
, but not change
s in the other properties like the ones updated on keyup
events on form.
Change it to:
this.listenTo( this.formsDataModelInst, 'change:loginp', this.render_home );
Upvotes: 0
Reputation: 35813
When you instantiate a View
you setup event bindings on the el
of that View
. It doesn't matter if a different View
also uses the same inputs
; as long as the first View
is still around its event handlers will continue to listen for and respond to events.
You had the right idea by trying to call this.unbind()
... except that View
s don't have an unbind
method. They do however have a undelegateEvents
method, which I think is what you're looking for.
Upvotes: 1