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、 andを使用してみてください。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 に答える