摘要:該內(nèi)的內(nèi)容會(huì)根據(jù)路由的變化而變化。配置,用來(lái)定義路由規(guī)則。由此我們就需要另一個(gè)第三方路由模塊,叫做,當(dāng)然它是基于開(kāi)發(fā)的。造成這種現(xiàn)象的最根本原因路由沒(méi)有明確的父子層級(jí)關(guān)系。監(jiān)聽(tīng)路由路由狀態(tài)發(fā)生改變時(shí)可以通過(guò)監(jiān)聽(tīng),通過(guò)注入實(shí)現(xiàn)狀態(tài)的管理。
何為路由
路由機(jī)制運(yùn)可以實(shí)現(xiàn)多視圖的單頁(yè)Web應(yīng)用(single page web application,SPA)。
單頁(yè)應(yīng)用在使用期間不會(huì)重新加載頁(yè)面,所有的數(shù)據(jù)交互由ajax完成。
非單頁(yè)應(yīng)用請(qǐng)求不同url,對(duì)SEO很不友善,而且刷新或發(fā)送url無(wú)法保留瀏覽進(jìn)度。
而單頁(yè)應(yīng)用前端擁有監(jiān)管url的權(quán)利,通過(guò)監(jiān)聽(tīng)頁(yè)面地址變化來(lái)調(diào)用前端MVC模塊,渲染不同頁(yè)面。當(dāng)然,前端這時(shí)也擁有了修改URL的能力,只需要管理好前端視圖與URL。在確定了需要保持的頁(yè)面后,前后端圍繞頁(yè)面各自負(fù)責(zé)視圖的渲染。
路由實(shí)現(xiàn) url不變?cè)捇?/b>這一種的情況是url完全不變,即你的頁(yè)面怎么改變,怎么跳轉(zhuǎn)url都不會(huì)改變。
這種情況的原理 就是純ajax拿到頁(yè)面模板后替換原頁(yè)面中的元素,重現(xiàn)渲染頁(yè)面。然而ajax的一個(gè)致命缺點(diǎn)就是導(dǎo)致瀏覽器后退按鈕失效。用戶體驗(yàn)很不好。
這種類型的優(yōu)點(diǎn)就是刷新頁(yè)面,頁(yè)面也不會(huì)丟。關(guān)于hash值的介紹鏈接
通過(guò)監(jiān)聽(tīng) hash(#)的變化來(lái)執(zhí)行js代碼 從而實(shí)現(xiàn) 頁(yè)面的改變
核心代碼:
window.addEventListener("hashchange",function(){ //code })
就是通過(guò)這個(gè)原理 只要#改變了 就能觸發(fā)這個(gè)事件,這也是很多單頁(yè)面網(wǎng)站的url中都也 (#)的原因
h5 history api這種類型是通過(guò)html5的最新history api來(lái)實(shí)現(xiàn)的。
通過(guò)pushState()記錄操作歷史,監(jiān)聽(tīng)window.onpopstate事件來(lái)進(jìn)行視圖切換,能正常的回退前進(jìn)。
這里是關(guān)于 history api的連接
關(guān)于這三種方法的demo往后會(huì)給大家提供完善,大家可以提醒我。
AngularJS 路由AngularJS 路由就是通過(guò)通過(guò)hash和h5 history兩種方式實(shí)現(xiàn)的,允許我們通過(guò)不同的 URL 訪問(wèn)不同的內(nèi)容。
通常我們的URL形式為 http://runoob.com/first/page,但在單頁(yè)Web應(yīng)用中 AngularJS 通過(guò) # + 標(biāo)記 實(shí)現(xiàn),例如:
http://cds.com/#/firstPage http://cds.com/#/secondPage
當(dāng)我們點(diǎn)擊以上的任意一個(gè)鏈接時(shí),向服務(wù)端請(qǐng)的地址都是一樣的 (http://runoob.com/)。 因?yàn)?# 號(hào)之后的內(nèi)容在向服務(wù)端請(qǐng)求時(shí)會(huì)被瀏覽器忽略掉。 所以我們就需要在客戶端實(shí)現(xiàn) # 號(hào)后面內(nèi)容的功能實(shí)現(xiàn)。
AngularJS 路由通過(guò) # + 標(biāo)記 幫助我們區(qū)分不同的邏輯頁(yè)面并將不同的頁(yè)面(View)綁定到對(duì)應(yīng)的控制器(controller)上。
下面我們介紹一下Angular的路由實(shí)現(xiàn)。
ngRouterngRouter是angular的一個(gè)多帶帶模塊。
我們看看他是怎么實(shí)現(xiàn)的。
1、加載實(shí)現(xiàn)路由的 js 文件:angular-route.js。
2、包含了 ngRoute 模塊作為主應(yīng)用模塊的依賴模塊。(為什么這么寫(xiě),下文介紹)
angular.module("routingDemoApp",["ngRoute"])
3、使用 ngView 指令。
該 div 內(nèi)的 HTML 內(nèi)容會(huì)根據(jù)路由的變化而變化。
4、配置 $routeProvider,AngularJS $routeProvider 用來(lái)定義路由規(guī)則。
angular.module("MyApp", ["ngRoute"]).config(["$routeProvider", function($routeProvider){ //$routeProvider 為我們提供了 when(path,object) & otherwise(object) 函數(shù)按順序定義所有路由,函數(shù)包含兩個(gè)參數(shù):第一個(gè)參數(shù)是 URL 或者 URL 正則規(guī)則。第二個(gè)參數(shù)是路由配置對(duì)象。 $routeProvider.when(url, { template: string,//在 ng-view 中插入簡(jiǎn)單的 HTML 內(nèi)容 templateUrl: string,//在 ng-view 中插入 HTML 模板文件 controller: string, function 或 array,//在當(dāng)前模板上執(zhí)行的controller函數(shù),生成新的scope。 controllerAs: string,//為controller指定別名。 redirectTo: string, function,//重定向的地址。 resolve: objectUI-Router//指定當(dāng)前controller所依賴的其他模塊。 }); $routeProvider.otherwise({redirectTo:"/"})//除配置路由外的其他路徑指向 }]);
在使用ngRouter時(shí)往往不能進(jìn)行視圖嵌套,而且功能有限,不能滿足開(kāi)發(fā)需求。由此我們就需要另一個(gè)第三方路由模塊,叫做 ui.router ,當(dāng)然它是基于ngRouter開(kāi)發(fā)的。
ui.Router提供了一種很好的機(jī)制,可以實(shí)現(xiàn)深層次嵌套。
1、在引入ui.route路由源文件
2、加載依賴模塊
angular.module("myApp", ["ui.router"]); // myApp為自定義模塊,依賴第三方路由模塊ui.router
在程序啟動(dòng)(bootstrap)的時(shí)候,加載依賴模塊(如:ui.router),將所有 掛載 在該模塊的 服務(wù)(provider) , 指令(directive) , 過(guò)濾器(filter) 等都進(jìn)行注冊(cè) ,那么在后面的程序中便可以調(diào)用了。
angular.module("myApp", ["ui.router","myFilter","myDirective","myService"]); //實(shí)際中只要依賴首頁(yè)需要用的模塊就可以。
3、定義視圖
//視圖展示 dash頁(yè)//定義導(dǎo)航
在視圖模板中還可以包含自己的 ui-view ,這就是我們可以支持嵌套路徑的原因。
4、配置 $stateProvider,在ui.router通過(guò)$stateProvider來(lái)定義路由規(guī)則
angular.module("MyApp").config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) { //$stateProvider為我們提供了state(pathName,object) & otherwise(object) 函數(shù)按順序定義所有路由,函數(shù)包含兩個(gè)參數(shù):第一個(gè)參數(shù)是 URL名稱(視圖中導(dǎo)航名稱)。第二個(gè)參數(shù)是路由配置對(duì)象。 $urlRouterProvider.otherwise("/dash.html"); //定義默認(rèn)跳轉(zhuǎn)和除配置之外的定向路由 $stateProvider .state("dash"(string), {//導(dǎo)航用的名字,如dash里的login url: "/dash.html"(string),//訪問(wèn)路徑,可視的路徑 template: string,//在 ui-view 中插入簡(jiǎn)單的 HTML 內(nèi)容 templateUrl: "views/dash.html"(string),//在 ui-view 中插入 HTML 模板文件(靜態(tài)文件路徑) data: {pageTitle: "系統(tǒng)主頁(yè)"}(object可以多層嵌套),//data數(shù)據(jù)不會(huì)注入到控制器,可以從父狀態(tài)向子狀態(tài)傳遞數(shù)據(jù) controller: "DashController",//在當(dāng)前模板上執(zhí)行的controller函數(shù),生成新的scope。 params:object,//params 選項(xiàng)是參數(shù)名稱(下文有栗子)。當(dāng)狀態(tài)激活的時(shí)候,應(yīng)用會(huì)使用這些參數(shù)填充 $stateParams 服務(wù)。 resolve: { deps: ["$ocLazyLoad", function ($ocLazyLoad) {//"$ocLazyLoad"是controller的依賴模塊,返回執(zhí)行方法。AngularJs 通過(guò) ocLazyLoad 實(shí)現(xiàn)動(dòng)態(tài)(懶)加載模塊和依賴。具體的有時(shí)間再擴(kuò)展。留個(gè)鏈接?。?! return $ocLazyLoad.load({ name: "MetronicApp", insertBefore: "#ng_load_plugins_before", files: [ "app/controllers/DashController.js", ] }); }] }//在下文介紹 }) }]);
resolve 功能路由嵌套
使用 resolve 功能,我們可以準(zhǔn)備一組用來(lái)注入到控制器中的依賴對(duì)象,在 uiRoute 中,resolve 可以在路由實(shí)際渲染之前解決掉 promise。
resolve 選項(xiàng)提供一個(gè)對(duì)象,對(duì)象中的 key 就是準(zhǔn)備注入 controller 的依賴名稱,值則是創(chuàng)建對(duì)象的工廠。
如果是一個(gè)字符串,就試圖用這個(gè)串來(lái)匹配當(dāng)前已經(jīng)注冊(cè)的服務(wù)名稱,
如果是一個(gè)函數(shù),執(zhí)行這個(gè)函數(shù),返回的值就是依賴。
如果函數(shù)返回一個(gè) promise,在控制器被實(shí)例化之前,將會(huì)被 resolved,返回的值被注入到 controller中。
先說(shuō)說(shuō)為什么要視圖嵌套,頁(yè)面一個(gè)主區(qū)塊顯示主內(nèi)容,主內(nèi)容中的部分內(nèi)容要求根據(jù)路由變化而變化,這時(shí)就需要另一個(gè)動(dòng)態(tài)變化的區(qū)塊嵌套在主區(qū)塊中。
如果用ngRoute 實(shí)現(xiàn)視圖嵌套,你會(huì)發(fā)現(xiàn)是不可能的,因?yàn)樵趎g-view指令link的過(guò)程中,代碼會(huì)無(wú)限遞歸下去。造成這種現(xiàn)象的最根本原因:路由沒(méi)有明確的父子層級(jí)關(guān)系。
而uiRouter很好的解決了這一問(wèn)題。
慣例先上代碼:
$stateProvider .state("parent", { abstract: true,//可以通過(guò)它解決依賴問(wèn)題,或者特定數(shù)據(jù)處理,或者簡(jiǎn)單地同樣的 url 來(lái)嵌套多個(gè)路由,例如,所有路由都在 /parent下面。 url: "/parent",//相對(duì)路徑=>…./index.html#/parent template: "I am parent "http://當(dāng)然你也可以寫(xiě)在templateUrl中 }) .state("parent.child", { url: "/child",//相對(duì)路徑=>…./index.html#/parent/child url:"^/child",//絕對(duì)路徑=>…./index.html#/child 注意寫(xiě)法區(qū)別 template: "I am child" }); 點(diǎn)我顯示父view內(nèi)容 點(diǎn)我顯示父view與子view內(nèi)容
巧妙地,通過(guò) parent 與 parent.child 來(lái)確定路由的 父子關(guān)系 ,從而解決無(wú)限遞歸問(wèn)題。另外子路由的模板最終也將被插入到父路由模板的div[ui-view]中去,從而達(dá)到視圖嵌套的效果。
多視圖效果多視圖:頁(yè)面可以顯示多個(gè)動(dòng)態(tài)變化的不同區(qū)塊。
原因在于,在ui.router中:可以給視圖命名(字符串),如:ui-view="status"??梢栽诼酚膳渲弥懈鶕?jù)視圖名字(如:status),配置不同的模板(其實(shí)還有controller等)。
放一段代碼
var app = angular.module("myApp", ["ui.router"]); app.config(["$stateProvider", function ($stateProvider) { $stateProvider .state("index", { url: "/index", views:{ "header":{template:"頭部?jī)?nèi)容"}, "nav":{template:"菜單內(nèi)容"}, "body":{template:"展示內(nèi)容"} } }) }]);
待完善(項(xiàng)目無(wú)涉及)(控制起來(lái)也很麻煩,處理不好都是坑,如果要用到再完善吧。)
視圖定位@的作用 是用來(lái)絕對(duì)定位view,即說(shuō)明該ui-view屬于哪個(gè)模板。
同樣放一段代碼
show index content111111 content222222var app = angular.module("myApp", ["ui.router"]); app.config(["$stateProvider", function ($stateProvider) { $stateProvider .state("index", { url: "/index", views:{ "index":{template:""}, //這里必須要絕對(duì)定位 "header@index":{template:"頭部?jī)?nèi)容header"}, "nav@index":{template:"菜單內(nèi)容nav"}, "body@index":{template:"展示內(nèi)容contents"} } }) //絕對(duì)定位 .state("index.content1", { url: "/content1", views:{ "body@index":{template:"content11111111111111111"} //"body@index"表時(shí)名為body的view使用index模板 } }) //相對(duì)定位:該狀態(tài)的里的名為body的ui-view為相對(duì)路徑下的(即沒(méi)有說(shuō)明具體是哪個(gè)模板下的) .state("index.content2", { url: "/content2", views:{ "body":{template:"content2222222222222222222"}// } }) }]);待完善(項(xiàng)目無(wú)涉及)(其實(shí)也不難理解,只是這個(gè)時(shí)間段任務(wù)重了,這里有時(shí)間再了解完善?。?/p> 路由傳參
Angular應(yīng)用通過(guò)通過(guò)$stateParams服務(wù)獲取參數(shù)他有兩種方式:(相對(duì)溫習(xí)一下路徑穿參方式,$location.search())
1.url: "/index/:id"
2.url: "/index/{id}"
注意這里只是兩種不同寫(xiě)法angular.module("MetronicApp").config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) { $stateProvider .state("dash", { url: "/dash.html/:orderId/:projectId", //或者注意是或者(這種需要直接定義好,或由頁(yè)面?zhèn)髦担? url:"/dash.html/{orderId}", //如果應(yīng)用訪問(wèn) /dash.html/42,那么,$stateParameter.orderId 就成為 42, 實(shí)際上, $stateParams 的值將為 { orderId: 42 } //或者(這種是在路由中定義好參數(shù)) url:"/dash.html", params: { orderId: { value: 42} } templateUrl: "/dash.html", controller: function ($stateParams,$scope) { //可以注入$stateParams服務(wù)來(lái)獲取你所傳遞的服務(wù) $scope.projectId=$stateParams.projectId; $scope.orderId=$stateParams.orderId; //42 } }) }]); //然后大家在看頁(yè)面中的寫(xiě)法 也是兩種方式建議用第二種() href傳參數(shù) ui-sref傳參數(shù)再來(lái)擴(kuò)展一下,在控制器中的頁(yè)面跳轉(zhuǎn),并且傳參
angular.module("MetronicApp",["ui.router"]); angular.module("MetronicApp").controller("MyCtrl", function($scope, $state,$location) { $scope.pathChange = function() { $state.go("dash",{name: 42}); //第一個(gè)參數(shù)是定義的urlName,第二個(gè)為參數(shù) }; $scope.pathChange = function() { $location.path("/sixth/detail/42"); //$location服務(wù)中有介紹 }; });可能大家會(huì)有疑問(wèn),我們項(xiàng)目的路徑和這個(gè)示例不一樣,這里的參數(shù)是angular是控制路徑跳轉(zhuǎn)的參數(shù)目的在與定向視圖或者視圖之間丶控制器之間的通信,不是從后臺(tái)請(qǐng)求的,這個(gè)要搞清楚。
和之前說(shuō)的$rootScope通信效果是一樣的。
監(jiān)聽(tīng)路由Angular 路由狀態(tài)發(fā)生改變時(shí)可以通過(guò)"$stateChangeStart"、"$stateChangeSuccess"、"$stateChangeError"監(jiān)聽(tīng),通過(guò)注入"$location"實(shí)現(xiàn)狀態(tài)的管理。
代碼示例如下:function run($ionicPlatform, $location, Service, $rootScope, $stateParams) { //路由監(jiān)聽(tīng)事件 $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) { console.log(event); //該事件的基本信息 console.log(toState); //我們可以得到當(dāng)前路由的信息,比如路由名稱,url,視圖的控制器,模板路徑等等 console.log(toParams); //我們可以得到當(dāng)前路由的參數(shù) console.log(fromState); //我們可以得到上一個(gè)路由的信息,比如路由名稱,url,視圖的控制器,模板路徑等等 console.log(fromParams); //我們可以得到上一個(gè)路由的參數(shù) if (toState.name == "dash") { //獲取參數(shù)之后可以調(diào)請(qǐng)求判斷需要渲染什么頁(yè)面,渲染不同的頁(yè)面通過(guò) $location 實(shí)現(xiàn) if (toParams.id == 10) { //$location.path();//獲取路由地址 // $location.path("/validation").replace(); // event.preventDefault()可以阻止模板解析 } } }) // stateChangeSuccess 當(dāng)模板解析完成后觸發(fā) $rootScope.$on("$stateChangeSuccess", function(event, toState, toParams, fromState, fromParams) { //code }) // $stateChangeError 當(dāng)模板解析過(guò)程中發(fā)生錯(cuò)誤時(shí)觸發(fā) $rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) { //code }) }在頁(yè)面渲染中 可通過(guò)"$viewContentLoading"和 "$viewContentLoaded"監(jiān)聽(tīng)頁(yè)面渲染狀態(tài):渲染開(kāi)始和渲染結(jié)束。(在控制器中添加以下代碼實(shí)現(xiàn)監(jiān)聽(tīng))
// $viewContentLoading- 當(dāng)視圖開(kāi)始加載,DOM渲染完成之前觸發(fā),該事件將在$scope鏈上廣播此事件。 $scope.$watch("$viewContentLoading",function(event, viewConfig){ alert("模板加載完成前"); }); //$viewContentLoaded- 當(dāng)視圖加載完成,DOM渲染完成之后觸發(fā),視圖所在的$scope發(fā)出該事件。 $scope.$watch("$viewContentLoaded",function(event){ alert("模板加載完成后"); });我們可以用這些監(jiān)聽(tīng)事件來(lái)判斷用戶傳參,權(quán)限判定等等。
工作原理我們了解一下uiRouter路由的工作原理
路由的創(chuàng)建
大致可以理解為:一個(gè) 查找匹配 的過(guò)程。就是將 hash值 (#xxx)與一系列的 "路由規(guī)則" 進(jìn)行查找匹配,匹配出一個(gè)符合條件的規(guī)則,然后根據(jù)這個(gè)規(guī)則,進(jìn)行數(shù)據(jù)的獲取,以及頁(yè)面的渲染。
我們分兩步學(xué)習(xí)我們通過(guò)調(diào)用 $stateProvider.state(...) 方法,創(chuàng)建了一個(gè)簡(jiǎn)單路由規(guī)則(詳情看上文)
當(dāng)我們反問(wèn)http://...index.html#/dash.html的時(shí)候,這個(gè)路由規(guī)則被匹配到,對(duì)應(yīng)的模板會(huì)被填到某個(gè) [ui-view] 中。
它做了些什么呢。首先,創(chuàng)建并存儲(chǔ)一個(gè)state對(duì)象,里面包含著該路由規(guī)則的所有配置信息。
然后,調(diào)用 $urlRouterProvider.when(...) 方法(上文說(shuō)過(guò)ui-router是基于ngRouter),進(jìn)行路由的 注冊(cè) (之前是路由的創(chuàng)建),代碼里是這樣寫(xiě)的:$urlRouterProvider.when(state.url, ["$match", "$stateParams", function ($match, $stateParams) { // 判斷是否是同一個(gè)state || 當(dāng)前匹配參數(shù)是否相同 if ($state.$current.navigable != state || !equalForKeys($match, $stateParams)) { $state.transitionTo(state, $match, { inherit: true, location: false }); } }]);當(dāng) hash值 與 state.url 相匹配時(shí),就執(zhí)行后面那段回調(diào),回調(diào)函數(shù)里面進(jìn)行了兩個(gè)條件判斷之后,決定是否需要跳轉(zhuǎn)到該state。
至于說(shuō)為什么說(shuō) "跳轉(zhuǎn)到該state,而不是該url"? 其實(shí) ui.router是基于state(狀態(tài))的,而不是url,之前就說(shuō)過(guò),路由存在著明確的 父子關(guān)系 ,每一個(gè)路由可以理解為一個(gè)state,當(dāng)程序匹配到某一個(gè)子路由時(shí),我們就認(rèn)為這個(gè)子路由state被激活,同時(shí),它對(duì)應(yīng)的父路由state也將被激活。我們還可以手動(dòng)的激活某一個(gè)state,就像上面寫(xiě)的那樣, $state.transitionTo(state, ...) ,這樣的話,它的父state會(huì)被激活(如果還沒(méi)有激活的話),它的子state會(huì)被銷(xiāo)毀(如果已經(jīng)激活的話)。
接著回到路由注冊(cè),路由注冊(cè)調(diào)用了 $urlRouterProvider.when(...) 方法,它創(chuàng)建了一個(gè)rule,并存儲(chǔ)在rules集合里面,之后的,每次hash值變化,路由重新查找匹配都是通過(guò)遍歷這個(gè) rules 集合進(jìn)行的。
路由的查找匹配當(dāng)路由的創(chuàng)建和注冊(cè),接下來(lái),就是路由的查找匹配了。這是一個(gè)復(fù)雜而又繁瑣的過(guò)程,繞到我都有點(diǎn)不想說(shuō)。
angular 在剛開(kāi)始的$digest(解析,臟查詢,能做的事情很多)時(shí), $rootScope 會(huì)觸發(fā) $locationChangeSuccess 事件(angular在每次瀏覽器hash change的時(shí)候也會(huì)觸發(fā) $locationChangeSuccess事件)ui.router 監(jiān)聽(tīng)了 $locationChangeSuccess 事件,于是開(kāi)始通過(guò)遍歷一系列rules,進(jìn)行路由查找匹配當(dāng)匹配到路由后,就通過(guò) $state.transitionTo(state,...) ,跳轉(zhuǎn)激活對(duì)應(yīng)的state最后,完成數(shù)據(jù)請(qǐng)求和模板的渲染
來(lái)上一段源碼function update(evt) { // ...省略 function check(rule) { var handled = rule($injector, $location); // handled可以是返回: // 1. 新的的url,用于重定向 // 2. false,不匹配 // 3. true,匹配 if (!handled) return false; if (isString(handled)) $location.replace().url(handled); return true; } var n = rules.length, i; // 渲染遍歷rules,匹配到路由,就停止循環(huán) for (i = 0; i < n; i++) { if (check(rules[i])) return; } // 如果都匹配不到路由,使用otherwise路由(如果設(shè)置了的話) if (otherwise) check(otherwise); } function listen() { // 監(jiān)聽(tīng)$locationChangeSuccess,開(kāi)始路由的查找匹配 listener = listener || $rootScope.$on("$locationChangeSuccess", update); return listener; } if (!interceptDeferred) listen();看懂的朋友就會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,每次路由變化(hash變化),由于監(jiān)聽(tīng)‘$locationChangeSuccess"事件,都要進(jìn)行rules的遍歷 來(lái)查找匹配路由,然后跳轉(zhuǎn)到對(duì)應(yīng)的state。我們之所以要循環(huán)遍歷rules,是因?yàn)橐檎移ヅ涞綄?duì)應(yīng)的路由(state),然后跳轉(zhuǎn)過(guò)去,倘若不循環(huán),也是能直接找到對(duì)應(yīng)的state。在用ui.router在創(chuàng)建路由時(shí):會(huì)實(shí)例化一個(gè)對(duì)應(yīng)的state對(duì)象,并存儲(chǔ)起來(lái)(states集合里面)。每一個(gè)state對(duì)象都有一個(gè)state.name進(jìn)行唯一標(biāo)識(shí)(如:"dash")。這時(shí)候就體現(xiàn)出 ui-sref指令的大作用了。
通過(guò)ui-sref跳轉(zhuǎn)到dash.html當(dāng)點(diǎn)擊這個(gè)a標(biāo)簽時(shí),會(huì)直接跳轉(zhuǎn)到dash.html,而并不需要循環(huán)遍歷rules。這個(gè)元素折行了一個(gè)方法,還是直接看代碼
element.bind("click", function(e) { // .. var transition = $timeout(function() { // 手動(dòng)跳轉(zhuǎn)到指定的state $state.go(ref.state, params, options); }); });ui-sref="dash"指令會(huì)給對(duì)應(yīng)的dom添加 click事件 ,然后根據(jù)dash(state.name),直接跳轉(zhuǎn)到對(duì)應(yīng)的state。
跳轉(zhuǎn)到對(duì)應(yīng)的state之后,ui.router會(huì)做一個(gè)善后處理,就是改變hash,此時(shí)就會(huì)觸發(fā)’$locationChangeSuccess"事件,然后執(zhí)行回調(diào),但是在回調(diào)中可以通過(guò)一個(gè)判斷代碼規(guī)避循環(huán)rules。
代碼段:function update(evt) { var ignoreUpdate = lastPushedUrl && $location.url() === lastPushedUrl; // 手動(dòng)調(diào)用$state.go(...)時(shí),直接return避免下面的循環(huán) if (ignoreUpdate) return true; }所以我們?cè)谑褂弥锌赏ㄟ^(guò)ui-serf來(lái)實(shí)現(xiàn)路由,達(dá)到視圖切換,或者在controller中調(diào)用 $state.go(....)來(lái)實(shí)現(xiàn)。
結(jié)語(yǔ)路由介紹的就這么多,但是任然要仔細(xì)逐行閱讀。也有一部分拓展,項(xiàng)目中沒(méi)有實(shí)際用到,但是也算是給優(yōu)化做一些思路。與大家共勉。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/92713.html
相關(guān)文章
AngularJS簡(jiǎn)述
流行框架 簡(jiǎn)介 angularjs是一款非常優(yōu)秀的前端高級(jí)JS框架,由谷歌團(tuán)隊(duì)開(kāi)發(fā)維護(hù),能夠快速構(gòu)建單頁(yè)web應(yīng)用,化繁為簡(jiǎn) 無(wú)論是angularjs還是jQuery都是用原生JS封裝的 庫(kù):對(duì)代碼進(jìn)行封裝,調(diào)用封裝的方法,簡(jiǎn)化操作 傳統(tǒng)方式是用get方式獲取元素,然后點(diǎn)方法 jQuery庫(kù)實(shí)現(xiàn)了對(duì)獲取方式的封裝,對(duì)方法的封裝 框架:提供代碼書(shū)寫(xiě)規(guī)則,按照規(guī)則去寫(xiě)代碼,框架會(huì)幫我們實(shí)現(xiàn)響應(yīng)的功能...
Vue面試中,經(jīng)常會(huì)被問(wèn)到的面試題/Vue知識(shí)點(diǎn)整理
摘要:可以在該鉤子中進(jìn)一步地更改狀態(tài),不會(huì)觸發(fā)附加的重渲染過(guò)程。我工作中只用到,對(duì)和不怎么熟與的區(qū)別相同點(diǎn)都支持指令內(nèi)置指令和自定義指令都支持過(guò)濾器內(nèi)置過(guò)濾器和自定義過(guò)濾器都支持雙向數(shù)據(jù)綁定都不支持低端瀏覽器。 看看面試題,只是為了查漏補(bǔ)缺,看看自己那些方面還不懂。切記不要以為背了面試題,就萬(wàn)事大吉了,最好是理解背后的原理,這樣面試的時(shí)候才能侃侃而談。不然,稍微有水平的面試官一看就能看出,是...
angularjs+springMvc學(xué)習(xí)筆記
摘要:回調(diào)說(shuō)白了,就是把函數(shù)當(dāng)參數(shù)傳給另一根函數(shù),在另一個(gè)函數(shù)執(zhí)行時(shí)調(diào)用此函數(shù)例如,在下面這段代碼中,上面定義了兩個(gè)函數(shù)和,下面的方法請(qǐng)求成功執(zhí)行,失敗執(zhí)行異步異步的原理我看了網(wǎng)上的一些博客和例子,大都以定時(shí)任務(wù)為例子說(shuō)明,但具體的原理我還是不太 回調(diào) 說(shuō)白了,就是把函數(shù)當(dāng)參數(shù)傳給另一根函數(shù),在另一個(gè)函數(shù)執(zhí)行時(shí)調(diào)用此函數(shù)例如,在下面這段代碼中,上面定義了兩個(gè)函數(shù)success和error,下...
angularjs+springMvc學(xué)習(xí)筆記
摘要:回調(diào)說(shuō)白了,就是把函數(shù)當(dāng)參數(shù)傳給另一根函數(shù),在另一個(gè)函數(shù)執(zhí)行時(shí)調(diào)用此函數(shù)例如,在下面這段代碼中,上面定義了兩個(gè)函數(shù)和,下面的方法請(qǐng)求成功執(zhí)行,失敗執(zhí)行異步異步的原理我看了網(wǎng)上的一些博客和例子,大都以定時(shí)任務(wù)為例子說(shuō)明,但具體的原理我還是不太 回調(diào) 說(shuō)白了,就是把函數(shù)當(dāng)參數(shù)傳給另一根函數(shù),在另一個(gè)函數(shù)執(zhí)行時(shí)調(diào)用此函數(shù)例如,在下面這段代碼中,上面定義了兩個(gè)函數(shù)success和error,下...
發(fā)表評(píng)論
0條評(píng)論
閱讀 1411·2019-08-30 15:44
閱讀 2186·2019-08-30 11:04
閱讀 583·2019-08-29 15:17
閱讀 2609·2019-08-26 12:12
閱讀 3194·2019-08-23 18:09
閱讀 977·2019-08-23 15:37
閱讀 1611·2019-08-23 14:43
閱讀 2998·2019-08-23 13:13