Маршрутизация — новая функция в 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 — метод в контроллере, который выполняется при переходе по нему (например: http://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.resume, это отменит маршруты только по этому хэш-токену, а остальные продолжат выполнение (вероятно, имелось в виду action.stop, — прим. перев.). Каждый токен должен быть разделён вертикальной линией:
#user/1234|message/5ga
Роутер разделит хэш и получит токены 'user/1234' и 'message/5ga'. Первым он обработает токен user, найдёт все маршруты, совпадающие с ним и выполнит их. Если не будет найдено ни одного маршрута, совпадающего с этим токеном, вызовется событие unmatchedroute. Затем роутер перейдёт к токену message и по аналогии найдёт связанные маршруты. Если не найдёт, вызовется событие unmatchedroute.
Заключение
Новый роутер в ExtJS 5 легко настраивается и позволяет также легко обрабатывать историю браузера, при этом он остаётся гибким и мощным, чтобы соотвествтовать требованиям сложных приложений. Вместе с MVC+VM, двунаправленным дата-биндингом и другими новыми функциями, Ext JS 5 — прекрасный фреймворк для корпоративных приложений.
Автор: alexstz