原文:How to Use Routing in Your Ext JS 5 Apps
简单介绍
Ext JS 5是一个重要的公布版本号,它提供了很多新特性来创建丰富的、企业级的Web应用程序。MVVM和双向数据绑定为开发者承担了大量的繁重工作。在Ext JS 5种,还有一个新特性就是路由,它能够在控制器内轻松的管理历史记录。前进和后退button是每个浏览器都会拥有的公共用户接口,如今,使用Ext JS 5在单页面应用程序中处理导航变得相当简单了。
Ext JS 5路由
在Ext JS,已经能够使用Ext.util.Histroy类来处理历史记录的变化,但在Ext JS 5,这个处理变得更easy和灵活。路由提供了一种更易于配置的方式来将散列值映射到控制器的方法,这包括使用參数和之前的行为来控制路由运行的流程,而在后端则使用Ext.util.History来处理。下面来看一个简单的样例:
Ext.define('MyApp.controller.Main', {
extend : 'Ext.app.Controller', routes : {
'home' : 'onHome'
}, onHome : function() {}
});
在路由对象中,keyword“home”就是要匹配的散列值,而值“onHome”就是控制器中的方法,当散列仅仅匹配的时候,就会运行该方法(比如:http://localhost#home)。要在控制器内改变散列值,能够使用redirectTo方法:
this.redirectTo(‘home’); //redirects to http://localhost#home
这将会将URL的散列值改动为“#home”,然后会运行MyApp.controller.Main控制器实例中路由所定义的的onHome方法。假设有多个控制器都匹配同样的散列值,运行的顺序将会依据应用程序实例的控制器数组中所定义的顺序运行。
散列值和參数
散列值还能够包括參数,路由可轻易的将他们作为參数传递给控制器的方法。带參数的散列值看起来像“#user/1234”,当中,1234是用户的ID,会被作为一个參数。能够通过下面方法来为控制器定义散列值:
Ext.define(‘MyApp.controller.Main', {
extend : 'Ext.app.Controller', routes : {
'user/:id' : 'onUser'
}, onUser : function(id) {}
});
在为路由配置一个预期的參数的时候,须要在參数名称前加入一个冒号,在以上样例中的參数就是“:id”,路由将会把匹配的不论什么值作为传递參数并传递给onUser方法。传递给控制器方法的參数的顺序与路由定义时的顺序同样。
还能够使用正則表達式来控制要匹配的散列值。在用户ID的演示样例中,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是一个包括參数和正則表達式字符串的对象。採用正則表達式字符串,而不是正則表達式的原因是,路由会依据路由内的參数创建一个默认的正則表達式,而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会象onUser方法一样接收id參数,只是,它还可获取到一个action參数。參数action包括有resume和stop方法用来控制路由的运行。运行action的resume方法,如Ext.Ajax.request的success处理中的那样,将会恢复路由的运行,这样就可实现路由的异步行为。运行action的stop方法,正如在failure回调函数中卡你打那样,会停止当前路由的运行。假设将true传递给stop方法,队列中的全部路由都会停止运行,这样就能够对路由实现完整的控制。
Ext JS应用程序可能会变得非常大非常复杂,并且有时候可能会希望在同一时间激活多个散列值。Ext JS 5有能力去处理多个散列值并分别去运行他们。单独的散列值会被沙盒化,这意味着假设须要取消一个路由,能够将true传递给action.resume方法,这就能够阻止该散列值的其它路由,而其它的散列值会继续运行。每个散列值都须要进行分隔,例如以下面演示样例的散列值:
#user/1234|message/5ga
路由会将散列值拆分为“user/1234”和“message/5ga”。路由会依据user的值去找到全部匹配的路由并运行不论什么匹配的路由。假设没有匹配散列值的路由,就会触发unmatchedroute事件。接下来,路由将会依据message的值来寻找不论什么匹配的路由并运行他们。假设没有匹配值的路由,将会触发unmatchedroute事件。
小结
Ext JS 5中的新的路由特性是处理浏览器历史堆栈的一直简单配置方式,它不单灵活,并且功能强大,足以满足复制的应用程序的须要。与MVC+VM、双向数据绑定和其它新特性在一起,使Ext JS 5成为了一个打造企业级应用程序的完美框架。
作者:Mitchell Simoens
Mitchell is a Senior Support Engineer providing support on the forums and the portal. Mitchell also is the maintainer of Sencha Fiddle and other web properties. Mitchell is also the co-author of "Sencha Touch in Action", and is a regular contributor of Ext JS and Sencha Touch frameworks, as well as extensions and plugins on GitHub.