大家好,我是IT修真院深圳分院第04期學(xué)員,一枚正直善良的web程序員。
今天給大家分享一下,修真院官網(wǎng) js任務(wù)中會(huì)使用到的知識(shí)點(diǎn):
如何使用ui-router?
1.背景介紹
Angular.js是一個(gè)用來(lái)構(gòu)建“富客戶端”的神奇JavaScript框架。但是事實(shí)卻是許多開發(fā)者卻不使用其內(nèi)置的路由模塊。反而使用AngularUI項(xiàng)目的
UI-Router模塊來(lái)代替之。
這是因?yàn)閁I-Router有兩個(gè)重要的特性:
*多樣化視圖
*嵌入式視圖
多樣化視圖
大多數(shù)的應(yīng)用程序都可以分解為一個(gè)一個(gè)區(qū)塊。最簡(jiǎn)單的情況,一個(gè)應(yīng)用程序有頭部(header),主體內(nèi)容(main content
area),以及一個(gè)尾部(footer)。通常一個(gè)應(yīng)用程序會(huì)有一個(gè)額外的側(cè)邊欄(sidebar)在頁(yè)面的左邊或者右邊,大多數(shù)用例中,這些區(qū)塊將同時(shí)顯示在頁(yè)面上。
Angular.js的內(nèi)置路由ngRoute只允許一個(gè)視圖(ng-view)出現(xiàn)在頁(yè)面上。這樣限制的情況下,人們可以使用包含頁(yè)面(ng-include)或者
其他的變通方法為應(yīng)用創(chuàng)建一個(gè)布局(layout)或主頁(yè)(master page)。
UI-Router支持多樣化視圖,并且每一個(gè)視圖都有自己相應(yīng)的控制,所以每個(gè)區(qū)塊都是封裝好,可以復(fù)用到整個(gè)應(yīng)用程序需要的地方。
嵌入式視圖
常見的例子中,一個(gè)應(yīng)用的嵌入式頁(yè)面一般是主頁(yè)的詳情頁(yè)面,更具體的說(shuō),就是列表的詳情頁(yè)面。許多應(yīng)用程序,都有列表頁(yè)面,點(diǎn)擊其中一個(gè)列表元素,可以進(jìn)入到列表的詳情頁(yè)面。更進(jìn)一步說(shuō),你點(diǎn)擊列表中一個(gè)行的連接,進(jìn)入一個(gè)可查看詳情頁(yè)面或是一個(gè)可編輯的表單。
如果列表頁(yè)面和詳情頁(yè)面是單獨(dú)分開的(或者他們被Angujar.js回調(diào)),使用Angular.js的內(nèi)置路由ngRoute是非常容易完成的。然而,如果你想要保持列表不變,而詳情頁(yè)面出現(xiàn)在列表的右邊或者下面,這樣就變得非常具有挑戰(zhàn)性了。
需要澄清的是,這樣的要求可以使用ngRoute來(lái)完成。但是你需要讓兩個(gè)控制器(一個(gè)用于列表,一個(gè)用于顯示和隱藏詳情)共享一個(gè)視圖。這樣的結(jié)果不是理想的,因?yàn)槲覀兿胍斜砗驮斍轫?yè)面有各自的控制器和視圖,并且職責(zé)單一(顯示列表或者顯示列表項(xiàng)目的詳情)。封裝這些用戶接口模塊到它們各自的視圖,這樣我們就有更多的“可組合UI”,允許我們將各個(gè)區(qū)塊整合到一起,或者根據(jù)需求拆分。嵌入式視圖,不僅能夠讓這些視圖同時(shí)出現(xiàn),還能讓一個(gè)視圖嵌入到另一個(gè)視圖中。
2.知識(shí)剖析
第一行,聲明AngularJS模塊,并把ui-router傳入AngularJS主模塊,所有的結(jié)合起來(lái)我們就得到了Angular模塊。
與集成的ngRoute服務(wù)不同的是,UI-Router可以將視圖嵌套,因?yàn)樗诘氖遣僮鳡顟B(tài)而僅非URL。與傳統(tǒng)做法使用ng-view不同的是,在ngRoute里需要使用ui-view服務(wù)。當(dāng)在ui-router中處理路由和狀態(tài)時(shí),開發(fā)者的重心是當(dāng)前的狀態(tài)是什么以及在哪一個(gè)頁(yè)面里。
和ngRoute一樣,為特定狀態(tài)指定的模板將會(huì)放在ui-view元素中。在這些模板中也可以包含自己的ui-view,這就是在同一個(gè)路由下實(shí)現(xiàn)嵌套視圖的方法。要定義一個(gè)路由,與傳統(tǒng)的方法相同:使用.config方式,但使用的不是$routeProvider而是$stateProvider。
$stateProvider:管理狀態(tài)定義、當(dāng)前狀態(tài)和狀態(tài)轉(zhuǎn)換。包含觸發(fā)狀態(tài)轉(zhuǎn)換的事件和回調(diào)函數(shù),異步解決目標(biāo)狀態(tài)的任何依賴項(xiàng),更新$location到當(dāng)前狀態(tài)。由于狀態(tài)包含關(guān)聯(lián)的url,通過(guò)$urlRouterProvider生成一個(gè)路由規(guī)則來(lái)執(zhí)行轉(zhuǎn)換的狀態(tài)。
$urlRouterProvider:管理了一套路由規(guī)則列表來(lái)處理當(dāng)$location發(fā)生變化時(shí)如何跳轉(zhuǎn)。最低級(jí)的方式是,規(guī)則可以是任意函數(shù),來(lái)檢查$location,并在處理完成時(shí)候返回true。支持正則表達(dá)式規(guī)則和通過(guò)$urlMatcherFactory編譯的UrlMatcher對(duì)象的url占位符規(guī)則。
ui-view指示器:渲染狀態(tài)中定義的視圖,是狀態(tài)中定義的視圖的一個(gè)占位符。
模板,模板路徑,模板Provider
上述代碼在設(shè)置對(duì)象上定義了一個(gè)叫start的狀態(tài)。設(shè)置對(duì)象stateConfig和路由設(shè)置對(duì)象的選項(xiàng)是非常相似的。開發(fā)者可以在每個(gè)視圖下使用如下方式來(lái)設(shè)置模板template -
HTML字符串,或者是返回HTML字符串的函數(shù)templateUrl - HTML模板的路徑,或者是返回HTML模板路徑的函數(shù)templateProvider,返回HTML字符串的函數(shù).
url選項(xiàng)將會(huì)為該應(yīng)用的狀態(tài)指定一個(gè)URL基于用戶瀏覽該應(yīng)用所在的狀態(tài)。這樣當(dāng)在瀏覽該應(yīng)用的時(shí)候便能實(shí)現(xiàn)深度鏈接的效果。
Views視圖
開發(fā)者可以在同一個(gè)模板中改變和切換不同的視圖。如果設(shè)置了視圖選項(xiàng),則該狀態(tài)的‘template’,‘templateUrl’及‘templateProvider’將被忽略。如果想在路由里包含父級(jí)模板,就需要?jiǎng)?chuàng)建一個(gè)包含模板的抽象模板。例如:
該函數(shù)需要兩個(gè)參數(shù):1.當(dāng)前的路徑,2.需要重定向到的路徑(或者是需要在路徑被訪問(wèn)是運(yùn)行的函數(shù))。設(shè)置重定向前需要為$urlRouterProvider設(shè)置when函數(shù)來(lái)接受一個(gè)字符串。例如,當(dāng)希望重定向一個(gè)空的路由到/inbox:
otherwise()
和ngRoute的otherwise()函數(shù)相似,在用戶提交的路徑?jīng)]有被定義的時(shí)候它將重定向到指定的頁(yè)面。這是個(gè)創(chuàng)建’默認(rèn)‘路徑的好方法。
otherwise()只接受一個(gè)參數(shù),要么函數(shù)要么字符串,字符串必須為合法的url路由地址,函數(shù)則會(huì)在沒(méi)有任何路徑被匹配的時(shí)候被運(yùn)行。
3.常見問(wèn)題
如何激活狀態(tài)?
有三種方式來(lái)激活特定的狀態(tài)
使用ui-sref綁定的連接
直接導(dǎo)航到與狀態(tài)關(guān)聯(lián)的url
使用$state.go()方法
4.解決方案
5.編碼實(shí)戰(zhàn)
6.擴(kuò)展思考
如何進(jìn)行嵌套路由?
7.參考文獻(xiàn)
AngularJS ui-router (嵌套路由)
8.更多討論
為什么綁定標(biāo)簽src屬性不解析ui-route嵌套路由?
angular.js中出于安全考慮,將帶有http://的網(wǎng)絡(luò)地址 當(dāng)做一個(gè)不安全的地址,所以需要對(duì)這個(gè)地址進(jìn)行處理才能使用
嵌套路由首先得引用ui-route.min.js文件
使用$sce.trustAsResourceUrl('xxx') 方法把這個(gè)字符串地址聲明為受信任的地址就可以