標籤:extjs 5 路由
原文:How to Use Routing in Your Ext JS 5 Apps
簡介
Ext JS 5是一個重要的發布版本,它提供了許多新特性來建立豐富的、企業級的Web應用程式。MVVM和雙向資料繫結為開發人員承擔了大量的繁重工作。在Ext JS 5種,另一個新特性就是路由,它可以在控制器內輕鬆的管理記錄。前進和後退按鈕是每個瀏覽器都會擁有的公用使用者介面,現在,使用Ext JS 5在單頁面應用程式中處理導航變得相當簡單了。
Ext JS 5路由
在Ext JS,已經可以使用Ext.util.Histroy類來處理記錄的變化,但在Ext JS 5,這個處理變得更容易和靈活。路由提供了一種更易於配置的方式來將散列值對應到控制器的方法,這包括使用參數和之前的行為來控制路由執行的流程,而在後端則使用Ext.util.History來處理。下面來看一個簡單的例子:
Ext.define(‘MyApp.controller.Main‘, { extend : ‘Ext.app.Controller‘, routes : { ‘home‘ : ‘onHome‘ }, onHome : function() {} });
在路由對象中,關鍵字“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方法。傳遞給控制器方法的參數的順序與路由定義時的順序相同。
還可以使用Regex來控制要匹配的散列值。在使用者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是一個包含參數和Regex字串的對象。採用Regex字串,而不是Regex的原因是,路由會根據路由內的參數建立一個預設的Regex,而conditions配置項的作用就是重寫預設的Regex字串。預設的Regex字串是“([%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.