之前有寫過一篇關(guān)于Angular自帶的路由:ngRoute。今天來說說Angular的第三方路由:ui-router。那么有人就會問:為什么Angular有了自帶的路由,我們還需要用ui-router呢?這里簡單明了的說明下ngRoute和ui-router的區(qū)別吧,其實(shí)也沒很大的區(qū)別,主要的就是ngRoute針對于單視圖,而ui-router可用于多視圖(這里說的視圖是指在頁面內(nèi)我們可控制的,可變化的區(qū)域)。
比如我們點(diǎn)擊了一個link,我們需要在視圖中跳轉(zhuǎn)到指定的一個頁面,那么ngRoute已經(jīng)滿足了我們的需求,而當(dāng)我們點(diǎn)擊的時候,需要在分別在不同的地方跳轉(zhuǎn)兩個不同的頁面的時候,ngRoute就不夠用了,我們就需要用到ui-router。
這里我們還是先來學(xué)習(xí)下ui-router(一些簡單的服務(wù)和用法)
ui-router
$urlRouterProvider
$urlRouterProvider負(fù)責(zé)監(jiān)聽$location.當(dāng)$location變化的時候,$urlRouterProvider開始在一個規(guī)則的列表中一個個的查找,直到找到匹配的值。$urlRouterProvider用于在后端指定url的狀態(tài)配置。所有的url被編譯成UrlMatcher對象。
依賴: $urlMatcherFactoryProvider $locationProvider
方法:
deferIntercept(defer);
禁用(或啟用)延遲location變化的攔截。如果你想定制與URL同步的行為(例如,你需要保持當(dāng)前的URL去并且推遲一個變化),那么在配置的時候使用這個方法。
參數(shù):
defer:boolean,確定是禁止還是啟用該攔截。
代碼:
angular.module('Demo',['ui.router']) .config(["$urlRouterProvider",function(){ $urlRouterProvider.deferIntercept(defer); // defer = true/false }])這是源碼部分:
this.deferIntercept = function (defer) { if (defer === undefined) defer = true; interceptDeferred = defer; // 默認(rèn)是true };otherwise(rule);
定義一個當(dāng)請求的路徑是無效路徑時跳轉(zhuǎn)的路徑。
rule:你想重定向的url路徑或一個返回的網(wǎng)址路徑的規(guī)則函數(shù)。函數(shù)傳入兩個參數(shù):$injector和$location服務(wù),而且必須返回一個string的url。
代碼:
angular.module('Demo',['ui.router']) .config(["$urlRouterProvider",function(){ $urlRouterProvider.otherwise(rule); // rule = 重定向的url規(guī)則 }])rule(rule);
定義使用$urlRouterProvider 來匹配指定的URL的規(guī)則。
參數(shù):
rule:將$injector和$location作為arguments傳入的處理函數(shù)。用來返回一個string類型的url路徑。
代碼:
angular.module('Demo',['ui.router']) .config(["$urlRouterProvider",function($urlRouterProvider){ $urlRouterProvider.rule(function ($injector, $location) { var path = $location.path(), normalized = path.toLowerCase(); if (path !== normalized) { return normalized; } }); }])when(what,handler);
為給定的URL匹配注冊一個處理程序。
參數(shù):
what:需要重定向的傳入路徑。
handler:你想要重定向的路徑/處理程序。
代碼:
angular.module('Demo', ['ui.router']); .config(["$urlRouterProvider",function ($urlRouterProvider) { $urlRouterProvider.when($state.url, function ($match, $stateParams) { if ($state.$current.navigable !== state || !equalForKeys($match, $stateParams) { $state.transitionTo(state, $match, false); } }); }]);$urlRouter
依賴:$location $rootScope $injector $browser
方法:href(urlMacther,params,options);
一個生成URL的方法,為給定的UrlMatcher返回編譯后的URL,并且用提供的參數(shù)填充。
參數(shù):
代碼:
$bob = $urlRouter.href(new UrlMatcher("/about/:person"), { person: "bob" }); // $bob == "/about/bob"; sync();sync();
觸發(fā)更新:發(fā)生在地址欄URL變化時執(zhí)行相同的更新。
$state
$state服務(wù)負(fù)責(zé)代表狀態(tài)及提供狀態(tài)之間的轉(zhuǎn)換。它還提供你當(dāng)前的狀態(tài)及上一個狀態(tài)。
依賴:$rootScope $q $view $injector $resolve $stateParams $urlRouter
方法:get(stateOrName,context);返回任何指定的狀態(tài)或所有狀態(tài)的配置對象。
參數(shù):
方法:
go(to,params,options);
參數(shù):
代碼:
$state.go('contact.detail');href(stateOeName,params,options);
一個URL生成方法,返回為給定的狀態(tài)填充指定的參數(shù)編譯后的鏈接。
參數(shù):
代碼:
$state.href("about.person", { person: "bob" })include(stateOrName,params,options);
一個確定當(dāng)前有效的狀態(tài)是不是與stateOrName平級的還是其子狀態(tài)。
參數(shù):
代碼:
<div ng-class="{highlighted:$state.includes('.item')}">Item</div> $state.$current.name = 'contacts.details.item'; $state.includes("contacts"); // true $state.includes("contacts.details"); // true $state.includes("contacts.details.item"); // true $state.includes("contacts.list"); // false $state.includes("about"); // false全局模式:
$state.$current.name = 'contacts.details.item.url'; $state.includes("*.details.*.*"); // true $state.includes("*.details.**"); // true $state.includes("**.item.**"); // true $state.includes("*.details.item.url"); // true $state.includes("*.details.*.url"); // true $state.includes("*.details.*"); // false $state.includes("item.**"); // falseis(stateOrName,params,options);
與$state.include相似,只是這個針對的是全名。參數(shù)性質(zhì)同上。
代碼:
<div ng-class="{highlighted: $state.is('.item')}">Item</div> $state.$current.name = 'contacts.details.item'; $state.is('contact.details.item'); // true $state.is(contactDetailItemStateObject); // truereload(state);
重新載入當(dāng)前狀態(tài)的方法。
參數(shù):
state:一個狀態(tài)名稱或者狀態(tài)對象。
代碼:
$state.reload('contact.detail');transitionTo(to,toParams,options);
過渡到一個新狀態(tài)的方法。
參數(shù):
代碼:
$state.transitionTo($state.current, $stateParams, { reload: true, inherit: false, notify: true });事件:
1 、$stateChangeError
路由狀態(tài)變化發(fā)生錯誤時觸發(fā)的事件。參數(shù)有:event,toState,toParams,fromState,fromParams,error。以上根據(jù)字面意思即可理解,哈哈。
2、$stateChangeStart
路由狀態(tài)變化發(fā)生前觸發(fā)的事件。參數(shù)有:event,toState,toParams,fromState,fromParams。
3、$stateChangeSuccess
路由狀態(tài)變化正確時觸發(fā)的事件。參數(shù)有:event,toState,toParams,fromState,fromParams。
4、$stateNotFound
路由狀態(tài)沒找到的時候觸發(fā)的事件。參數(shù)有:event,unfoundState,fromState,fromParams。
$stateProvider
處理路由狀態(tài)的服務(wù),路由的狀態(tài)反映了該項(xiàng)在應(yīng)用程序中的位置,描述了在當(dāng)前狀態(tài)下UI是應(yīng)該怎么樣的,并且該做什么。
依賴:$urlRouterProvider $urlMatcherFactoryProvider
方法:
decorator(name,func);
通過內(nèi)部的$stateProvider以擴(kuò)展或者重寫狀態(tài)生成器。可用于添加ui-router的自定義功能,例如,基于狀態(tài)名稱推斷templateUrl。
警告:因?yàn)樯善鞯暮瘮?shù)執(zhí)行順序的不確定,decorator不應(yīng)該相互依賴。
參數(shù):
代碼:
$stateProvider.decorator('views', function (state, parent) { var result = {}, views = parent(state); angular.forEach(views, function (config, name) { var autoName = (state.name + '.' + name).replace('.', '/'); config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html'; result[name] = config; }); return result; }); $stateProvider.state('home', { views: { 'contact.list': { controller: 'ListController' }, 'contact.item': { controller: 'ItemController' } } }); $state.go('home');以上代碼修飾了“views”直接通過state的名稱綁定完對應(yīng)的頁面模板。
state(name,stateConfig);
注冊一個狀態(tài),并給定其配置。
參數(shù):
ui-sref
一種將鏈接(<a>標(biāo)簽)綁定到一個狀態(tài)的指令。點(diǎn)擊該鏈接將觸發(fā)一個可以帶有可選參數(shù)的狀態(tài)轉(zhuǎn)換。
代碼:
<a ui-sref="app.index">首頁</a> <!-- 這里是正常的跳轉(zhuǎn) --> <a ui-sref="app.index({id:yourId})">你的主頁</a> <!-- 這里是帶參數(shù)對象的跳轉(zhuǎn),名稱是id,值是yourId -->簡單的使用代碼(ui-router的單視圖):
<div ng-app="Demo" ng-controller="testCtrl as ctrl"> <ol> <li><a ui-sref="app">app</a></li> <li><a ui-sref="test">test</a></li> </ol> <div ui-view></div> <script type="text/ng-template" id="'page1.html'"> this is page 1 for app. </script> <script type="text/ng-template" id="'page3.html'"> this is page 1 for test. </script> </div>
angular.module('Demo', ['ui.router']) .config(["$stateProvider","$urlRouterProvider",routeConfig]) .controller("testCtrl", angular.noop) function routeConfig($stateProvider,$urlRouterProvider){ $urlRouterProvider.otherwise("/app"); $stateProvider .state("app",{ url:"/app", templateUrl:"'page1.html'" }) .state("test",{ url:"/test", templateUrl:"'page3.html'" }) }使用代碼(ui-router的多視圖):
<div ng-app="Demo" ng-controller="testCtrl as ctrl"> <ol> <li><a ui-sref="app.page1">app</a></li> <li><a ui-sref="test.page1({id:1})">test</a></li> </ol> <div ui-view></div> <script type="text/ng-template" id="'layout.html'"> <div ui-view="nav@"></div> <div ui-view></div> </script> <script type="text/ng-template" id="'nav1.html'"> <ol> <li><a ui-sref="app.page1">app.page1</a></li> <li><a ui-sref="app.page2">app.page2</a></li </ol> </script> <script type="text/ng-template" id="'nav2.html'"> <ol> <li><a ui-sref="test.page1({id:1})">test.page1</a></li> <li><a ui-sref="test.page2">test.page2</a></li </ol> </script> <script type="text/ng-template" id="'page1.html'"> this is page 1 for app. </script> <script type="text/ng-template" id="'page2.html'"> this is page 2 for app. </script> <script type="text/ng-template" id="'page3.html'"> this is page 1 for test. </script> <script type="text/ng-template" id="'page4.html'"> this is page 2 for test. </script> </div> angular.module('Demo', ['ui.router']) .config(["$stateProvider","$urlRouterProvider",routeConfig]) .controller("testCtrl", angular.noop) function routeConfig($stateProvider,$urlRouterProvider){ $urlRouterProvider.otherwise("/app/page1"); $stateProvider .state("app",{ url:"/app", views:{ "":{ templateUrl:"'layout.html'" }, "nav":{ templateUrl:"'nav1.html'" } } }) .state("app.page1",{ url:"/page1", templateUrl:"'page1.html'" }) .state("app.page2",{ url:"/page2", templateUrl:"'page2.html'" }) .state("test",{ url:"/test", views:{ "":{ templateUrl:"'layout.html'" }, "nav":{ templateUrl:"'nav2.html'" } } }) .state("test.page1",{ url:"/page1?:id", templateUrl:"'page3.html'", controller:["$stateParams",function($stateParams){ console.log($stateParams.id);// 1 這里實(shí)現(xiàn)傳參 }], params:{ id:null } }) .state("test.page2",{ url:"/page2", templateUrl:"'page4.html'" }) }注意:需要引入angular-ui-router[.min].js
這里本獸沒有也不會把全部用法寫一遍 -。- 寫兩個簡單的案例僅供學(xué)習(xí)參考。這里偷個懶,把代碼都寫在一個頁面上完成了... 畢竟花了兩個晚上的空閑時間用來整理內(nèi)容和寫demo 考慮到第二天要上班,都是盡量的早睡,所以整理資料拖的久了些。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。
新聞熱點(diǎn)
疑難解答