這裏是修真院前端小課堂,每篇分享文從javascript
【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】html
八個方面深度解析前端知識/技能,本篇分享的是:前端
【angularJS的兩種路由ng-router和ui-router的差別】vue
你們好,我是IT修真院深圳分院第07期學員,一枚正直善良的web程序員。html5
今天給你們分享一下,修真院官網 JS-06任務中可能會使用到的知識點:java
1.背景介紹
angular路由nginx
AngularJS 路由容許咱們經過不一樣的 URL 訪問不一樣的內容。程序員
經過 AngularJS 能夠實現多視圖的單頁Web應用(single page web application,SPA)。angularjs
說了那麼多,那麼,什麼是路由呢?web
AngularJs中的路由,應用比較普遍,主要是容許咱們經過不一樣的url訪問不一樣的內容,可實現多視圖的單頁web應用。下面看看具體怎麼使用。
一般咱們的URL形式爲http://jtjds.cn/first/page,但在單頁web應用中angularjs經過#+標記實現,好比下面的頁面,將是下文中的路由列子:
http://192.168.1.109:8000/angular-program/src/main.html#/pagetable/page1
http://192.168.1.109:8000/angular-program/src/main.html#/pagetable/page2
http://192.168.1.109:8000/angular-program/src/main.html#/pagetable/page3
當咱們點擊以上任一一個連接時,向服務器請求的地址都是http://192.168.1.109:8000/angular-program/src/main.html ,而#號以後的內容在向服務器端請求時會被瀏覽器忽略掉,因此咱們在客戶端實現#號後面的功能實現便可。簡單來講,路由經過#+標記幫助咱們區分不一樣邏輯頁面,並將其綁定到對應的控制器上。
路由介紹
每一個頁面均有一個控制器控制,經過路由,從而將不一樣的頁面展現出來。
二.知識剖析
ng-Route使用方法
1)引入 angular-route lib
不管是 ngRoute 仍是 ui.router ,做爲框架額外的附加功能,都必須以 模塊依賴 的形式被引入,並且要注意,須要先引用angular,這是由於angular-router.js須要傳入window.angular這個參數,這個參數只有在加載angular纔會出現。
<script src="../../bower_components/angular/angular.js"></script> <script src="lib/angular-route.js"></script> 2)配置路由 var app = angular.module('ngRouteApp', ['ngRoute']); app.config(function($routeProvider){ $routeProvider .when('/Main', { templateUrl: "main.html", controller: 'MainCtrl' }) .otherwise({ redirectTo: '/tabs' });
服務與指令
ngRoute 路由模塊名
$routeProvider 服務提供者,用來定義一個路由表,即地址欄與視圖模板的映射,對應於 ui.router 中的 urlRouterProvider 和 stateProvider
$route 服務,完成路由匹配,而且提供路由相關的屬性訪問及事件,如訪問當前路由對應的 Controller,對應於下面的 $urlRouter 和 $state
$routeParams 服務,保存了地址欄中的參數,對應於下面的 $stateParams
ng-view 指令,用來在主視圖中指定加載子視圖的區域,對應於下面的 ui-view
ui-router使用方法
1)引入js文件
<script type="text/javascript" src="JS/angular.min.js"></script> <script type="text/javascript" src="JS/angular-ui-router.min.js"></script>
2)注入ui-router模塊
var app = angular.module('myApp', ['ui.router']); app.config(function($urlRouterProvider, $stateProvider) { $urlRouterProvider.otherwise("/index"); //這條是至關於報錯的時候跳轉 $stateProvider .state("Main", { url: "/main", templateUrl: "main.html", controller: 'MainCtrl' })
服務與指令
ui.router 路由模塊名 $urlRouterProvider 服務提供者,用來配置路由重定向 $stateProvider 服務提供者,用來配置路由 $urlRouter 服務 $state 服務,用來顯示當前路由狀態信息,以及一些路由方法(如:跳轉) $stateParams 服務,用來存儲路由匹配時的參數 ui-view 指令,路由模板渲染,對應的 dom 相關聯 ui-sref 指令,連接到特定狀態
三.常見問題
多視圖
多樣化視圖.jpg
大多數的應用程序均可以分解爲一個一個區塊。最簡單的狀況,一個應用程序有頭部(header),主體內容(main content area),以及一個尾部(footer)。
一般一個應用程序會有一個額外的側邊欄(sidebar )在頁面的左邊或者右邊。
大多數用例中,這些區塊將同時顯示在頁面上。Angular.js 的內置路由ngRoute只容許一個視圖(ng-view)出如今頁面上。
<div ng-view></div> <div ng-view></div>
由於ng-router沒法命名ng-view,而ui-router則能夠經過命名ui-view來實現顯示不一樣的視圖出如今頁面上
//html部分 <div ui-view></div> <div ui-view="login"></div> //js部分 .state("login.page1",{ url:"/page1", views:{ '':{template:"page2"}, 'login':{template:"hello"} } })
能夠給視圖命名,如:ui-view=」status」。
能夠在路由配置中根據視圖名字(如:status),配置不一樣的模板(其實還有controller等)。
嵌套視圖
嵌套視圖:頁面某個動態變化區塊中,嵌套着另外一個能夠動態變化的區塊。
嵌入式視圖.jpg
其實,嵌套視圖,在html中的最終表現就像這樣:
<div ng-view> session <div ng-view>article</div> </div> 轉成javascript,咱們會在程序裏這樣寫: .when('/error', { template: '<div ng-view>error</div>' }) </code>
一運行,報了一個這樣的錯誤:
RangeError: Maximum call stack size exceeded
發現瀏覽器崩潰了,由於 ng-view 會陷入死循環,無限遞歸下去。
使用 ui.router 能很容易解決這個問題,由於它定義的路由有明確的父子關係,並經過 ui-view 指令將子路由模版插入到父路由模板的ui-view中去,從而實現視圖嵌套。看代碼:
$stateProvider .state("login",{ url:"/login", templateUrl:"login.html" //controller: 'loginCtr' //選擇控制器 也能寫成 loginCtr as login }) .state("login.page1",{ url:"/page1", template:"page1" }) .state("login.page2",{ url:"/page2", template:"page2" }) .state("login.page3",{ url:"/page3", template:"page3" })
四.解決方案
須要澄清的是,這樣的要求可使用ngRoute來完成。可是你須要讓兩個控制器(一個用於列表,一個用於顯示和隱藏詳情)共享一個視圖。這樣的結果不是理想的,由於咱們想要列表和詳情頁面有各自的控制器和視圖,而且職責單一(顯示列表或者顯示列表項目的詳情)。封裝這些用戶接口模塊到它們各自的視圖,這樣咱們就有更多的「可組合UI」,容許咱們將各個區塊整合到一塊兒,或者根據需求拆分。嵌入式視圖,不只可以讓這些視圖同時出現,還能讓一個視圖嵌入到另外一個視圖中。
五.代碼實戰
六.拓展思考
單頁web應用(SPA)的簡單介紹
單頁 Web 應用 (single-page application 簡稱爲 SPA) 是一種特殊的 Web 應用。它將全部的活動侷限於一個Web頁面中,僅在該Web頁面初始化時加載相應的HTML、JavaScript 和 CSS。一旦頁面加載完成了,SPA不會由於用戶的操做而進行頁面的從新加載或跳轉。而是利用 JavaScript 動態的變換HTML的內(採用的是div切換顯示和隱藏),從而實現UI與用戶的交互。因爲避免了頁面的從新加載,SPA 能夠提供較爲流暢的用戶體驗。得益於ajax,咱們能夠實現無跳轉刷新,又多虧了瀏覽器的histroy機制,咱們用hash的變化從而能夠實現推進界面變化.
爲了單頁面應用的要求(改變視圖的同時不會向後端發出請求。),瀏覽器當前提供瞭如下兩種支持hash和history:
hash —— 即地址欄 URL 中的 # 符號(此 hash 不是密碼學裏的散列運算)。
好比這個 URL:http://www.abc.com/#/hello,hash 的值爲 #/hello。它的特色在於:hash 雖然出如今 URL 中,但不會被包括在 HTTP 請求中,對後端徹底沒有影響,所以改變 hash 不會從新加載頁面。
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(須要特定瀏覽器支持)
這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的 back、forward、go 的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會當即向後端發送請求。
若是不想要很醜的 hash,咱們能夠用路由的 history 模式,這種模式充分利用 history.pushState API 來完成
URL 跳轉而無須從新加載頁面。—— Vue-router 官網。
router去掉#
ui.router原理是改變location.hash的值,而location.hash 原本就是指 URL 裏 # 符號及其後的部分,若是你是要作路由映射而且不想用基於 hash 的方案,那你應該考慮 HTML5 的 History API
$location服務支持配置兩種URL格式:Hashbang模式(默認)和HTML5模式。兩種模式下的API都是通用的。
靜態網站,咱們須要修改的地方包含三個文件
index.html : ng-app的定義文件
app.js : 對應ng-app的控制文件
nginx.conf : nginx的網站配置文件
編輯 index.html,增長base標籤。
在head標籤裏增長一行
<base href="/工程名/"> 編輯app.js,增長 $locationProvider.html5Mode(true) book.config(['$routeProvider', '$locationProvider', '$sceProvider', 'tplProvider', function ($routeProvider, $locationProvider, $sceProvider, tplProvider) { $routeProvider .when('/', {templateUrl: tplProvider.html('welcome'), controller: 'WelcomeCtrl'}) .when('/book', {templateUrl: tplProvider.html('book'), controller: 'BookCtrl'}) //圖書 .when('/book-r1', {templateUrl: tplProvider.html('book-r1'), controller: 'BookR1Ctrl'}) //R的極客理想 .when('/video', {templateUrl: tplProvider.html('video'), controller: 'VideoCtrl'}) //視頻 .when('/about', {templateUrl: tplProvider.html('about'), controller: 'AboutCtrl'}) //關於做者 .otherwise({redirectTo: '/'}); $locationProvider.html5Mode(true); }]);
編輯nginx的配置文件,增長try_files配置。
server { set $htdocs /www/deploy/mysite/onbook; listen 80; server_name onbook.me; location / { root $htdocs; try_files $uri $uri/ /工程名/index.html =404; } }
七.參考文獻
AngularJs ng-route路由詳解
深究AngularJS——ui-router詳解
AngularJS中ngRouter和uiRouter的區別
多樣化視圖與嵌套視圖
八.更多討論
hash和history的好處是什麼?
一、#! #很難看,不美觀
二、微信支付接口,使用hash的話能夠忽略#後的內容,只需定義主頁的支付
三、seo優化,url#後的內容不會被收錄
什麼是路由?什麼是NG路由?
簡單來講,路由就是給指定的頁面分配一個url地址。經過這個url地址,你就能訪問到該頁面了。
好比你寫了一個頁面,/static/public/game/index.html,你的服務器項目域名http:www.dsxxx.com你經過一些方式,給該頁面配置了一個路由地址/game那麼,你就能夠經過http:www.dsxxx.com/game訪問到...,都是經過一些方式作了配置的,具體的方式你能夠隨着學習的深刻逐步瞭解到
NG路由天然是angularjs中使用的路由,天然也有vue-router,React-router等等
在路由中定義controller有什麼意義,和直接在js裏定義controller的區別是什麼?
在angularjs中controller有三種寫法
第一種
<pre name="code" class="javascript">var AppController = ['$scope', function($scope){ $scope.notifyServiceOnChage = function(){ console.log($scope.windowHeight); }; }]; app.controller('AppController',AppController);
在定義AppController的時候,先聲明方法須要注入的參數,而後再定義方法體。最後將AppController綁定到app上。
第二種
app.controller('AppController', function($scope){ $scope.notifyServiceOnChage = function(){ console.log($scope.windowHeight); }; })
直接在app的controller屬性定義,首先是controller名字,而後是方法體。
第三種
function AppController($scope) { $scope.notifyServiceOnChage = function(){ console.log($scope.windowHeight); }; }
直接寫方法,而後在ng-controller引用該方法。