Pull to refresh

Как использовать Routing в Ext JS 5

Reading time4 min
Views14K
Original author: Mitchell Simoens

Маршрутизация — новая функция в Ext JS 5, которая позволяет связывать историю навигации с контроллером. Кнопки «Назад/Вперёд» — одна из основных частей интерфейса браузеров и с Ext JS 5 сделать навигацию в одностраничных приложениях стало очень просто.

Routing в Ext JS 5


Ext JS всегда позволял обрабатывать историю навигации при помощи класса Ext.util.History, но в Ext JS 5 мы сделали этот процесс ещё проще и гибче. Роутер предоставляет простую конфигурацию связи хэш-токенов и методов контроллера с поддержкой параметров и контролем выполнения маршрута (за кулисами используется Ext.util.History). Посмотрим на простой пример:

    Ext.define('MyApp.controller.Main', {
        extend : 'Ext.app.Controller',
 
        routes : {
            'home' : 'onHome'
        },
 
        onHome : function() {}
    });


В объекте routes ключ home — это хэш, а onHome — метод в контроллере, который выполняется при переходе по нему (например: localhost#home). Чтобы изменить хэш внутри котнроллера, можно использовать метод redirectTo:

 this.redirectTo(‘home’); //редиректит на http://localhost#home

Это изменит хэш URL на #home, что в свою очередь вызовет метод onHome, где контекстом будет экземпляр контроллера MyApp.controller.Main, в котором был определён маршрут. Если у вас в нескольких контроллерах прописан одинаковый маршрут, то очерёдность выполнения будет такой, в какой прописаны контроллеры приложения (массив controllers).

Хэш-токены и параметры


Хэш-токен может содержать параметры, а роутер передаёт их в методы контроллера как аргументы. Хэш может выглядеть как '#user/1234', где 1234 — ID пользователя. Чтобы совпадать с таким хэшем, контроллер конфигурируется следующим образом:

    Ext.define(‘MyApp.controller.Main', {
        extend : 'Ext.app.Controller',
 
        routes : {
            'user/:id' : 'onUser'
        },
 
        onUser : function(id) {}
    });

При конфигурации маршрута с параметрами перед именем параметра ставится двоеточие. В данном случае это :id. Роутер возьмёт любое переданное значение и передаст его в метод onUser. Порядок аргументов, передаваемых в метод, совпадает с порядком параметров, определённом в маршруте.

Вы можете контроллировать совпадение параметров хэша, используя регулярные выражения. В примере выше ID может содержать только числа, а остальные значения совпадать не должны. Для этого используется конфиг conditions:

    Ext.define('Fiddle.controller.Main', {
        extend : 'Ext.app.Controller',
 
        routes : {
            'user/:id' : {
                action     : 'onUser',
                conditions : {
                    ':id' : '([0-9]+)'
                }
            }
        },
 
        onUser : function(id) {}
    });

Этот пример показывает две вещи: маршрут может быть объектом, в котором ключ action — метод контроллера, а conditions — объект с параметрами и строками регулярных выражений. Причина, по которой регулярное выражение записывается в строке в том, что роутер создаёт основное выражение, основываясь на параметрах маршрута. Конфиг conditions позволяет переопределить регулярные выражения по умолчанию. Регулярное выражение по умолчанию для строковых параметров — '([%a-zA-Z0-9\\-\\_\\s,]+)'.

Чтобы обработать переход по маршруту, для которого нет совпадений, существует событие unmatchedroute. Его обработчик можно повесить как на приложение, так и на контроллер. Например, на контроллер:

    Ext.define('Fiddle.controller.Main', {
        extend : 'Ext.app.Controller',
 
        listen : {
            controller : {
                '*' : {
                    unmatchedroute : 'onUnmatchedRoute'
                }
            }
        },
 
        onUnmatchedRoute : function(hash) {}
    });

Иногда бывает нужно отловить переход по маршруту, чтобы прекратить его выполнение или продолжить после выполнения какого-нибудь асинхронного действия, например, ajax-запроса. Для этого в маршруте используется ключ before. Вот пример, в котором выполнение маршрута продолжается после ajax-запроса:

    Ext.define('Fiddle.controller.Main', {
        extend : 'Ext.app.Controller',
 
        routes : {
            'user/:id' : {
                action     : 'onUser',
                before     : 'beforeUser',
                conditions : {
                    ':id' : '([0-9]+)'
                }
            }
        },
 
        beforeUser : function(id, action) {
            Ext.Ajax.request({
                url     : '/user/confirm',
                params  : {
                    userid : id
                },
                success : function() {
                    action.resume();
                },
                failure : function() {
                    action.stop();
                }
            });
        },
 
        onUser : function(id) {}
    });

В методе beforeUser принимается аргумент id по аналогии с onUser, а также — action, в котором есть методы resume и stop, контроллирующие выполнение маршрута. Метод action.resume() продолжит маршрут, позволяя делать его асинхронным, а action.stop() — предотвратит его выполнение. Если в метод stop передать аргумент true, то выполнение всех маршрутов будет остановлено.

Приложения Ext JS становятся больше и сложнее, и они могут требовать обработки нескольких хэш-токенов одновременно. В Ext JS 5 эта возможность реализована, при этом, каждый хэш-токен обрабатывается отдельно в своей песочнице. Это означает, что если вы отменяете один маршрут, передавая true в метод action.stop, это отменит маршруты только по этому хэш-токену, а остальные продолжат выполнение. Каждый токен должен быть разделён вертикальной линией:

    #user/1234|message/5ga

Роутер разделит хэш и получит токены 'user/1234' и 'message/5ga'. Первым он обработает токен user, найдёт все маршруты, совпадающие с ним и выполнит их. Если не будет найдено ни одного маршрута, совпадающего с этим токеном, вызовется событие unmatchedroute. Затем роутер перейдёт к токену message и по аналогии найдёт связанные маршруты. Если не найдёт, вызовется событие unmatchedroute.

Заключение


Новый роутер в ExtJS 5 легко настраивается и позволяет также легко обрабатывать историю браузера, при этом он остаётся гибким и мощным, чтобы соотвествтовать требованиям сложных приложений. Вместе с MVC+VM, двунаправленным дата-биндингом и другими новыми функциями, Ext JS 5 — прекрасный фреймворк для корпоративных приложений.
Tags:
Hubs:
+13
Comments5

Articles