Search code examples
extjssencha-touchsencha-touch-2

Sencha Touch: Clicking a button rapidly will push a view twice


Say I have a button that triggers a push of a new view. I noticed that if I click it more than once, fast enough, it will push the same view twice.

You can mimic this behavior using their official docs on this page, where they have a live sample: http://docs.sencha.com/touch/2-0/#!/guide/navigation_view

the clear question is, simply how to prevent it?


Solution

  • Masking successfully prevents double tapping problem.

    In my code I'm using two functions for mask/unmask navigation container:

    /**
     * Mask container with rolling wheel. Usually need if Ajax-request is sent to the server and app waiting for response
     * Best practice is masking the current navigator container, to prevent blocking whole app. Method warns if no container
         * is defined. In some cases warning could be suppress with parameter
         *
         * @param container
         * @param {boolean} [suppressWarning]
         */
        startLoading: function(container, suppressWarning) {
            var loadingComponent = container;
    
            if (!loadingComponent) {
                // <debug>
                if (!suppressWarning) {
                    console.warn('Please define navigator container for non-blocking operation, or define suppressWarning parameter');
                }
                // </debug>
                loadingComponent = Ext.Viewport;
            }
    
    //      var lastMaskedContainer = container;
            this.lastMaskedContainer = container;
    
            loadingComponent.setMasked({
                xtype: 'loadmask',
                message: 'Loading...'
            });
    
    /*
            Ext.defer(function() {
                lastMaskedContainer.setMasked(false);
            }, Pipedrive.app.maskingTimeout * 1000)
    */
        },
    
        /**
         *
         * @param {Ext.Container} container
         * @param {boolean} [suppressWarning]
         */
        stopLoading: function(container, suppressWarning) {
            var loadingComponent = container;
    
            if (!loadingComponent) {
                // <debug>
                if (!suppressWarning) {
                    console.warn('Please define either navigator container for non-blocking operation, or define suppressWarning parameter');
                }
                // </debug>
                loadingComponent = Ext.Viewport;
            }
    
            var alreadyMasked = loadingComponent.getMasked();
    
            var lastMaskedContainer = this.lastMaskedContainer;
            if (!alreadyMasked && !suppressWarning) {
                // <debug>
                if (lastMaskedContainer != container) {
                    console.warn('Found Start/Stop Loading inconsistency. Please revise code'
                        + (container ? '. Container: ' + container.getId() : 'Ext.Viewport')
                        + (lastMaskedContainer ? ', last masked container: ' + lastMaskedContainer.getId() : '')
                    );
                }
                // </debug>
                loadingComponent = Ext.Viewport;
            }
            loadingComponent.setMasked(false);
        }
    

    than in the tap handler:

    onDealDetailsTap: function(ct) {
        console.log('onDealDetailsTap', ct);
        var form = ct.getReferenceForm(),
            navigatorContainer = this.getNavigatorContainer(form),
            model = form.getRecord();
    
        UiHelper.startLoading(navigatorContainer);
        Ext.Viewport.fireEvent('detailfields', {
            title: model.get('title'),
            id: model.get('id'),
            store: 'DealFields',
            navigatorContainer: navigatorContainer
        })
    },
    

    to cleanup the loading mask:

    control : {
        activitiesContainer: {
            push: 'onPushActivitiesContainer'
        },
    
    
    
    
    onPushActivitiesContainer: function(ct) {
        //console.log('onPushActivitiesContainer', ct);
        UiHelper.stopLoading(ct);
    },
    

    especially it is cool for waiting for long-timed ajax requests....

    Cheers, Oleg