重新渲染后不触发backbone.js事件 [英] backbone.js events not firing after re-render
问题描述
我有一个视图,渲染时上面有一个带有点击事件的登录按钮.首先呈现所有作品:单击按钮,成功调用 ajax 后,登录提示消失并显示欢迎视图 (LoggedInView).但是,如果我稍后导航回此视图 (#foo),UI 会呈现但事件关联消失,而无需通过调用 delegateEents() 手动强制问题.
I have a View that when rendered has a login button on it with a click event attached. First render all works: click on button and upon successful ajax call the login prompts disappear and welcome view (LoggedInView) is displayed. But, if I navigate back to this View later (#foo) the UI renders but the event association is gone without manually forcing the issue by calling delegateEents().
我的事件没有重新关联是怎么回事?
What happened that my events didn't re-associate themselves?
LoginView = Backbone.View.extend({
template: _.template($("#loginTemplate").html()),
initialize: function(stuff,router) {
_.bindAll(this,'render','rc','gotProfile');
this.model.bind("rc",this.rc)
this.router = router;
},
events: {
'click .loginButton': 'login'
},
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
$(this.el).find(".actionButton").button(); // Button
// this.delegateEvents(this.events); // NEEDED! Re-wire events on re-render
return this;
},
rc: function(code) {
switch(code) {
case errCodes.USER_NOT_FOUND: this.notFound(); break;
case errCodes.OK: this.loginOk(); break;
default: this.otherErr(); break;
}
},
login: function() {
clearErrors( $('[rel="req"]') );
var okReq = validate( $('#login [rel="req"]'), validateReq );
var okEmail = validate( [$('#uid')], validateEmail );
if( okReq && okEmail ) {
this.model.set({'uid':$('#uid').val().trim(), 'pwd':$('#pwd').val().trim()});
this.model.fetch();
}
},
notFound: function() {
validate( [$('#uid'),$('#pwd')], function(){return[false,"Invalid user / password"]} );
},
otherErr: function() {
validate( [$('#uid'),$('#pwd')], function(){return[false,"Please contact support for help logging in."]} );
},
loginOk: function() {
this.profile = new Profile({uid:this.model.get('uid'),token:this.model.get('key')});
this.profile.bind("rc",this.gotProfile)
this.profile.fetch();
},
gotProfile: function() {
this.router.navigate('/',true);
}
});
LoggedInView = Backbone.View.extend({
template: _.template($("#loggedInTemplate").html()),
uList: new ProfileList(),
initialize: function() {
_.bindAll(this,'render','renderUserList','renderUser');
this.model.bind('show', this.render);
this.uList.bind('rc', this.render);
},
events: {
'click #ufa': 'getUsersForHouse'
},
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
this.renderUserList();
// this.delegateEvents(this.events); // NEEDED! Re-wire events on re-render
return this;
},
renderUserList: function() {
$(this.el).find('ul').empty();
this.uList.each(this.renderUser);
},
renderUser: function(aUser) {
$(this.el).find('#userList').append("<li>"+aUser.get('person').firstName+"</li>");
},
getUsersForHouse: function() {
this.uList.fetch(this.model.get('token'),"house");
}
});
Main = Backbone.Router.extend({
routes: {
'foo': 'foo',
'*all': 'home'
},
initialize: function() {
this.token = new Token();
this.loginView = new LoginView({model:this.token},this);
},
foo: function(){ // naving here looses click event on login button
$('#login').empty();
$("#login").append(this.loginView.render().el);
},
home: function() {
$('#login').empty();
if( this.loginView.profile == null )
$("#login").append(this.loginView.render().el);
else {
this.loggedInView = new LoggedInView({model:this.loginView.profile});
$("#login").append(this.loggedInView.render().el);
}
}
});
推荐答案
您清空了 #login div.正如 jQuery 文档所说:
You empty the the #login div. As the jQuery doc says:
为了避免内存泄漏,jQuery 删除了其他构造,例如数据和子元素中的事件处理程序,然后再删除元素本身.
To avoid memory leaks, jQuery removes other constructs such as data and event handlers from the child elements before removing the elements themselves.
因此,您正在有效地从视图中删除事件.我更喜欢使用 detach,因为它保留事件.http://api.jquery.com/detach/
So you are effectively removing events from your views. I prefer to use detach because it keeps events. http://api.jquery.com/detach/
您可以在视图中实现显示/隐藏来解决这个问题.
You can implement a show/hide in your views that will deal with this.
这篇关于重新渲染后不触发backbone.js事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!