我正处于骨干的真正瓶颈中。我是新手,如果我的问题很愚蠢,我很抱歉,因为我可能没有明白系统结构的重点。
基本上,我正在创建广告应用程序,它可以让您为不同的“步骤”做一些事情。因此,我实现了某种分页系统。每次页面满足特定条件时,显示下一页链接,并缓存当前页面。
每个页面都使用相同的“页面”对象模型/视图,并且每次都将导航附加到那里。无论如何它只注册了一次,当旧页面淡出而新页面淡入时,我取消委托/重新委托事件。
如果我总是对以前的页面使用缓存版本,一切都很好。但是,如果我重新渲染已经渲染的页面,当我单击“转到下一页”时,它会跳过我重新渲染页面本身的次数。
就像“转到下一页”按钮已经注册了 3 次,并且从未从事件侦听器中删除。
就代码而言,这是一个很长的应用程序,我希望你能理解基本思想,并给我一些提示,而不需要在这里有完整的代码。
在此先感谢,我希望有人可以帮助我,因为我正处于真正的瓶颈中!
ps由于某种原因,我注意到下一个/上一个按钮各自的html没有缓存在页面中。诡异的。
---UPDATE--- 我尝试了stopListening 建议,但没有奏效。这是 jmy 麻烦的按钮:
// Register the next button
App.Views.NavNext = Backbone.View.extend({
el: $('#nav-next'),
initialize: function() {
vent.on('showNext', function() {
this.$el.fadeIn();
}, this)
},
events: {
'click': 'checkConditions'
},
checkConditions: function() {
//TODO this is running 2 times too!
console.log('checking conditions');
if (current_step == 1)
this.go_next_step();
vent.trigger('checkConditions', current_step); // will trigger cart conditions too
},
go_next_step: function() {
if(typeof(mainView.stepView) != 'undefined')
{
mainView.stepView.unregisterNavigation();
}
mainView.$el.fadeOut('normal', function(){
$(this).html('');
current_step++;
mainView.renderStep(current_step);
}); //fadeout and empty, then refill
}
});
基本上, checkConditions 运行 2 次,就好像之前渲染的点击仍然被注册一样。这是它被注册的地方,然后在当前步骤消失后取消注册(只是该视图的一部分!):
render: function() {
var step = this;
//print the title for this step
this.$el.attr('id', 'step_' + current_step);
this.$el.html('<h3>'+this.model.get('description')+'</h3>');
// switch display based on the step number, will load all necessary data
// this.navPrev = new App.Views.NavPrev();
// this.navNext = new App.Views.NavNext();
this.$el.addClass('grid_7 omega');
// add cart (only if not already there)
if (!mainView.cart)
{
mainView.cart = new App.Models.Cart;
mainView.cartView = new App.Views.Cart({model: mainView.cart})
mainView.$el.before(mainView.cartView.render().$el)
}
switch (this.model.get('n'))
{
case 5: // Product list, fetch and display based on the provious options
// _.each(mainView.step_values, function(option){
// console.log(option)
// }, this);
var products = new App.Collections.Products;
products.fetch({data:mainView.step_values, type:'POST'}).complete(function() {
if (products.length == 0)
{
step.$el.append('<p>'+errorMsgs['noprod']+'</p>')
}
else {
step.contentView = new App.Views.Products({collection: products});
step.$el.append(step.contentView.render().$el);
}
step.appendNavigation();
});
break;
}
//console.log(this.el)
return this;
},
appendNavigation: function(back) {
if(current_step != 2)
this.$el.append(navPrev.$el.show());
else this.$el.append(navPrev.$el.hide());
this.$el.append(navNext.$el.hide());
if(back) navNext.$el.show();
navPrev.delegateEvents(); // re-assign all events
navNext.delegateEvents();
},
unregisterNavigation: function() {
navNext.stopListening(); // re-assign all events
}
最后,这是主视图的 renderStep,在按下“下一步”后调用它会加载缓存版本(如果存在),但对于问题页面,我没有创建它
renderStep : function(i, previous) { // i will be the current step number
if(i == 1)
return this;
if(this.cached_step[i] && previous) // TODO do not render if going back
{ // we have this step already cached
this.stepView = this.cached_step[i];
console.log('ciao'+current_step)
this.stepView.appendNavigation(true);
if ( current_step == 3)
{
_.each(this.stepView.contentView.productViews, function(pview){
pview.delegateEvents(); //rebind all product clicks
})
}
this.$el.html(this.stepView.$el).fadeIn();
} else {
var step = new App.Models.Step({description: steps[i-1], n: i});
this.stepView = new App.Views.Step({model: step})
this.$el.html(this.stepView.render().$el).fadeIn(); // refill the content with a new step
mainView.cached_step[current_step] = mainView.stepView; // was in go_next_step, TODO check appendnavigation, then re-render go next step
}
return this;
}