Wiki

Clone wiki

ExtJSPackages / Routes Before Filter

This package allows to configure a method to be executed before every route action. Sadly at this moment only one method per controller.

##How to use it##

Install the package:

#!bash
$ sencha repo add alfonsonishikawa https://alfonsonishikawa.bitbucket.io/extjspackages/pkgs
$ sencha package install nishilua-routes-before-filter

Add it to your app.json:

#!json
    requires: [
        .... ,
        "nishilua-routes-before-filter"
    ],
It will be downloaded automatically when doing:
#!bash
$ sencha app watch

Configure a filter in your ViewControllers:

#!javascript
Ext.define('GoraExplorer.view.main.MainController', {
    extend: 'Ext.view.ViewController',

    routesBeforeFilter: 'loginBeforeFilter',

    // Normal routes, but the filter will be executed before this ones
    routes: {
        home: 'onHome',
        login: 'onLogin'
    },

As an example, the filter could be something like:

#!javascript
    /**
     * Defaut route before filter that allows '/login' route for everyone
     * and checks authentication on the rest.
     * @param {String} actionHash
     * @param {Object} resumeOrStop
     */
    loginBeforeFilter: function(actionHash, resumeOrStop) {
        var me = this ;

        if (actionHash == 'login') {
            resumeOrStop.resume();
        } else {
            me.ifLoggedIn() // Asynchronous checking if the user is logged in (or remember-me, etc.)
                .then(function() {
                    resumeOrStop.resume();
                })
                .otherwise(function() {
                    me.redirectTo('login', true); // We can rediret to other hashUrl. Beware of infinite loops
                    resumeOrStop.stop(true); // true => empty the queue and avoids executing the route
                })  ;
        }
    },

    privates: {

        /**
         * Returns a promise that checks if the user is logged in (the viewmodel property
         * 'currentUser' would be set), and try to load it's data otherwise.
         *
         * Will try to load the user data from a REST service configured in the model.
         * On success executes the resolve() and the viewmodel will have the user data loaded.
         * On error executes the reject().
         *
         * @returns {Ext.Promise}
         * @private
         */
        ifLoggedIn: function () {
            var me = this,
                deferred = new Ext.Deferred();

            if (me.getViewModel().get('currentUser').get('enabled')) { // Synchronous
                deferred.resolve();
            } else {
                // Asynchronous
                me.getViewModel().get('currentUser').load({
                    scope: me,
                    failure: function (record, operation) {
                        deferred.reject(record, operation);
                    },
                    success: function (record, operation) {
                        deferred.resolve(record, operation);
                    }
                });
            }

            return deferred.promise;
        }
    }

Configuring this example in an abstract ViewController will affect all the routes in every ViewController inherited.

##Before filter signature##

The before filter signature is function(actionHash, resumeOrStop):

  • actionHash: the hash of the action of the url (without parameters - at least by now)
  • resumeOrStop: object interface for asynchronous implementations, as in "before" methods per action. Must always execute .resume() to execute the action or .stop(true) to stop executing the action. Notice the true parameter.

It is allowed to redirect to other hashed routes, as shown in the example.

Updated