0

我正处于骨干的真正瓶颈中。我是新手,如果我的问题很愚蠢,我很抱歉,因为我可能没有明白系统结构的重点。

基本上,我正在创建广告应用程序,它可以让您为不同的“步骤”做一些事情。因此,我实现了某种分页系统。每次页面满足特定条件时,显示下一页链接,并缓存当前页面。

每个页面都使用相同的“页面”对象模型/视图,并且每次都将导航附加到那里。无论如何它只注册了一次,当旧页面淡出而新页面淡入时,我取消委托/重新委托事件。

如果我总是对以前的页面使用缓存版本,一切都很好。但是,如果我重新渲染已经渲染的页面,当我单击“转到下一页”时,它会跳过我重新渲染页面本身的次数。

就像“转到下一页”按钮已经注册了 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;
        }
4

1 回答 1

0

当您在屏幕上显示或删除某个视图时,请尝试使用listenTo和。stopListening

看看文档:http ://backbonejs.org/#Events-listenTo

所有事件都在视图初始化时绑定,当您从屏幕上删除视图时,请取消绑定所有事件。

阅读本文进行详细分析: http: //lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

于 2013-02-27T10:55:38.757 回答