route 路由
在AngularJS里面有兩種方式實現路由,第一個是$location,第二個就是route。
在這里,我先介紹route模塊.
由於AngularJS是模塊化的,我們要引用路由,就需要先將這個包下載下來。
npm install angular-route --save
或者使用bower
bower install angular-route --save
之后,在我們的文件引入AngularJS-route.js文件,就可以使用route路由了.
由於route是一個單獨的模塊,我們想要使用,必須要在自己的模塊中添加對ngRoute模塊的依賴.
var app = angular.module('myApp', ['ngRoute']);
然后,我們需要通過config方法來配置.
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/a', {
controller: 'aController',
templateUrl: './a.html'
})
.when('/b', {
controller: 'bController',
templateUrl: './b.html'
})
.when('/c', {
controller: 'cController',
templateUrl: './c.html'
})
.otherwise({
redirectTo:'/a'
});
}]);
注意,上面的config也要注入一個對象,后綴也是Provider.
config里面注入的對象都要跟上Provider,即使后面有Provider.
when表示匹配,如果有對應的路由匹配上, 那么就會進入相應的控制器.
otherwise表示如果沒有匹配到,就走'\a'.
下面是控制器代碼:
app.controller('aController', ['$scope', function ($scope) {
$scope.msg = 'this is aController';
}])
app.controller('bController', ['$scope', function ($scope) {
$scope.msg = 'this is bController';
}])
app.controller('cController', ['$scope', function ($scope) {
$scope.msg = 'this is cController';
}])
注冊了三個控制器(注意,這里的控制器不用在View里面通過ng-controller申明.
好了
現在我們需要在html文件里面加上ng-app指令和ng-view指令
注意:ng-view 指令是一個特殊的指令,它的作用是在html中給$route對應的視圖占位.(ng-view是優先級為1000的終極指令,AngularJs不會運行作用在同一個指令上的其他指令.)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div ng-app="myApp">
<div ng-view></div>
</div>
<script src="./../angular.js"></script>
<script src="./../angular-route.js"></script>
<script src="index.js"></script>
</body>
</html>
下面是我的三個html文件
a.html
<h2>
{{msg}}
</h2>
b.html
<h2>
{{msg}}
</h2>
c.html
<h2>
{{msg}}
</h2>
好了,所有的文件都已經寫好了,似乎已經可以打開了,我們試試
上面什么都沒有顯示!!
我們使用F12打開控制台
我們看到了關鍵字 XMLHttpRequest,這是一個ajax對象.
明白了,AngularJs加載a.html,b.html,c.html時通過ajax方式的,而File協議是不支持ajax方式的?
怎么辦呢?
辦法就是起一個Web服務器.
現在主流的IDE都會自動以http方式在瀏覽器中查看文件,比如,WebStorm,HBuilder,Sublime也有對應的插件. Sublime Server.
但遺憾的是,VScode沒有,
VSCode通過
ext install view in-browser
安裝插件可以打開瀏覽器,但也是file協議.
npmJs社區提供了一個Web服務器,叫做 http-server
可以通過npm方式安裝.
npm install http-server -g
現在可以使用命令
hs -o[path]
打開一個服務,
注意: 雖然路徑名是可選的,但是還是需要寫上,因為這個在第一個啟動的時候會記住url地址,以后雖然在別的路徑下啟動服務,還是只會跳轉到第一個url上.
好了,
它會啟動一個端口8080的服務,並會打開我的資源管理器(我資源管理器使用了clover插件).
然后我們在瀏覽器地址欄輸入
http://127.0.0.1:8080/01route/index.html
注意: /表示網站根目錄,一定要使用我上面開啟服務的路徑作為網站根目錄.
它會默認跳轉到http://127.0.0.1:8080/01route/index.html#/a 並打開
是不是歐了 哈哈哈哈
當然,你也可以不使用這種方式,使用IIS或者其它的Web服務器. 但是我太不喜歡IIS啦(其實我以前做ASP.NET過的... 囧),
嗯,雖然這么做可行,但是有一個弊端,看下面的圖
它每次都要請求a.html,b.html,c.html,如果文件多起來,是不是很麻煩呢?
由於在html里面,script標簽在html5中可以省略type="text/javascript",默認會作為JavaScript文件解析,但是我們我們聲明為其他的類型,html就不會做為JavaScript解析了,而是一個普通的節點. AngularJs就是利用這個特點,實現了在一個頁面上放置多個View.
看下面的代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script id="a_html" type="text/ng-template">
{{msg}}
</script>
<script id="b_html" type="text/ng-template">
{{msg}}
</script> <script id="c_html" type="text/ng-template">
{{msg}}
</script>
</head>
<body>
<ul>
<li>
<a href="#/a">a視圖</a>
</li>
<li>
<a href="#/b">b視圖</a>
</li>
<li>
<a href="#/c">c視圖</a>
</li>
</ul>
<div ng-app="myApp">
<div ng-view></div>
</div>
<script src="./../angular.js"></script>
<script src="./../angular-route.js"></script>
<script src="index2.js"></script>
</body>
</html>
js代碼有稍微的變化
var app = angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/a', {
controller: 'aController',
templateUrl: './a_html'
})
.when('/b', {
controller: 'bController',
templateUrl: './b_html'
})
.when('/c', {
controller: 'cController',
templateUrl: './c_html'
})
.otherwise({
redirectTo:'/a'
});
}]);
app.controller('aController', ['$scope', function ($scope) {
$scope.msg = 'this is aController';
}])
app.controller('bController', ['$scope', function ($scope) {
$scope.msg = 'this is bController';
}])
app.controller('cController', ['$scope', function ($scope) {
$scope.msg = 'this is cController';
}])
下面看效果:
但是,有時候比如一個班級的信息統計,我需要查看每個同學的詳細信息,比如 ..#/tom,那么還有#/linda,在這里如果為每個學生都寫一個模板是不是太浪費了? 而且每個學生之間的信息模板都是相同的,不同的就是數據,而數據是可以通過控制器來提供的. 所以在這種情況下,只需要聲明一個模板就並且只匹配一次.
看下面的代碼:
index2.html
<!--/*
* @Author: Pawn.Hu
* @Date: 2016-08-14 13:48:39
* @Last Modified by: Pawn.Hu
* @Last Modified time: 2016-08-14 13:48:39
*/-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<ul>
<li>
<a href="#/student/Tom">Tom</a>
</li>
<li>
<a href="#/student/Linda">Linda</a>
</li>
<li>
<a href="#/student/Taylor">Taylor</a>
</li>
</ul>
<div ng-app="myApp">
<div ng-view></div>
</div>
<script src="./../angular.js"></script>
<script src="./../angular-route.js"></script>
<script src="index2.js"></script>
</body>
</html>
這里申明了3個錨點
index2.js
var app = angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/student/:name', {
controller: 'studentController',
templateUrl: './student.html'
}).otherwise({
redirectTo: '/student/Tom'
});
}])
app.controller('studentController', ['$scope', '$routeParams', function ($scope, $routeParams) {
var name = $routeParams.name;
$scope.name = name;
}])
這里when方法第一個參數后面的冒號表示后面是一個路由參數.
注意: $routeProvider.when('/student/:name', { ... }) 這里when的后面還可以跟上一個?號,表示沒有也能匹配成功,但是通常情況下不會跟otherwise合用.,而且AngularJS路由模塊只有這兩個特殊符號.
這里是student.html 模板
<h1>
{{name}}
</h1>
下面看效果
注意觀察地址欄的變化.(我的書簽就不用看了,都是沒用的東西.
這就是AngularJS的路由基礎,但是功能還是相對比較薄弱,
ui-router 這是一個獨立的模塊,並不包含在AngularJs中,可以進行嵌套路由和一些非常復雜的路由,會在后面介紹.
好了,關於AngularJS 基礎的路由模塊就介紹到這里,下面Angular路由(二) 我會介紹下$location服務和AngularJS路由架構,其實,在真正開發中,我們並不是按照上面的方式來使用路由.
希望能對你提供幫助.