AngularJS是单页面应用的,所以能够从页面的一个视图跳转到另一个视图就格外重要。随着应用越来越复杂,就需要一个合理统一的方式来管理视图。现在我们除了用ng-include指令在视图中引入模板以外,现在还可以用$route服务声明路由来实现这个功能。实现步骤可以分成以下几步:
一、引入安装
在AngularJS版本1.2以后,ngRoute就成为一个独立的模块,需要安转引用才能正常的使用路由功能:可以从 https://angularjs.org/ 下载,下载来的压缩包里会包含angular-route.js,或者也可以使用Bower,npm等方式安装,最后也需要将angular-route.js引入
<script type="text/javascript" src="js/lib/angular.js"></script>
<script type="text/javascript" src="js/lib/angular-router.js"></script>
在HTML中要引入这两个js文件,需要注意的是:angular.js要先于angular-route.js引入
var myRoute = angular.module('myRoute',['ngRoute']);
myRoute.config(['$routeProvider',function($routeProvider){
//代码
}]);
最后,要把ngRoute模块在我们的应用中依赖加载进来
二、定义路由表
服务$routeProvider提供了定义路由表的服务,包括两个核心的方法:when(path,route) , otherwise(params),下面是一个简单的例子
var myApp = angular.module('myApp',['ngRoute']);
myApp.config(['$routeProvider',function($routeProvider){
$routeProvider.when('/login',{
templateUrl : '/view/main.html',
controller : 'LoginController'
}).when('/homePage',{
templateUrl : '/view/homepage.html',
controller : 'HomeController'
}).otherwise(
redirectTo : '/view/main.html'
)
}]);
when(path, route)
path:这个参数是路由路径,这个路径会和$location.path当前URL路径进行匹配,所以这个path是相对路径,可以在后面接参数(:name),如果想要在上面的控制器访问到name这个参数,需要在控制器里依赖$routeParams服务,例如:
.controller('HomeController',['$scope','$routeParams',function($scope,$routeParams){
//代码
}]);
$routeProvider.when('/home/:name',{
templateUrl:'/view/homepage.html',
controller:'HomeController'
})
route:这个参数是配置对象,用来设置当匹配path后具体做什么,可以进行设置的属性有:
- template :类似指令的模板;
- templateUrl :一个带路径的模板(视图);
- controller :可以是字符串或者函数,控制器。会将模板和控制器进行关联(如果是字符串的话,就是是一个已注册的控制器名称)
- redirectTo :字符串或者函数,字符串就是路径被替换成的值,函数就是路径会被替换为函数的返回值;
- reloadOnSearch :true或者false,主要用于路由嵌套和原地分页等需求;
- resolve :如果设置了这个属性,AngularJ会将列表中的元素都注入到对应控制器中
一个复杂的路由,会包含多个路由,以及一个可以将所有意外路径进行重定向的捕获器otherwise
三、在主视图中添加加载子视图的位置
需要在HTML页面使用ng-view来为$route对应的试图占位置:
//方法一:
<div ng-view> </div>
//方法二:
<ng-view> </ng-view>
按照上面的三部就能成功的使用路由,在浏览器输入地址查看一下:http://127.0.0.1:8080/KMF-TongXin/pages/index.html#/login。
这个地址其中http://127.0.0.1:8080/KMF-TongXin/pages/index.html就是前面说的$location.path,匹配到了/login,所以会把templateUrl里面指定的main.html模板加载到index.html里面ngView占的位置上。至于这个#,就又引出了路由模式这个概念。
路由模式
不同的路由模式在浏览器的地址栏中会以不同的URL格式呈现。有两种路由模式:标签模式和HTML5模式。$location服务默认使用标签模式进行路由,上面的例子就是标签模式的,。路由模式决定URL长什么样。
(1)标签模式
也就是常见的hashbang。标签模式是HTML5模式的降级方案,URL路径会以#符号开头,这种模式下的URL看起来是这样的:
http://127.0.0.1:8080/KMF-TongXin/pages/index.html#/login
(2)HTML5模式
这种模式下的URL和普通的URL看起来无异(老式的浏览器看来可能还是标签模式),例如上面的地址用HTML5模式是这样的:http://127.0.0.1:8080/KMF-TongXin/pages/index.html/login,当浏览器不支持HTML5模式时,$location服务会自动使用标签模式的URL
两种模式的不同点:
- HTML5模式会重写<a href=" "> </a>中的链接,标签模式则不需要;
- HTML5模式下需要后端服务器也支持URL重写,服务器还需要确保所有的请求都返回index.html。但是在标签模式,不需要任何服务器端的支持;
- HTML5模式下应不要使用相对路径,容易造成不能正确处理路由,标签模式就没有这种说法
关于路由的其他应该注意的地方:
1> $location服务不会重新加载整个页面
我们在实现页面跳转的时候常用方法是:$location.path('/home');但是这个并没有重新加载整个页面,如果想重新加载整个页面的话请使用:
window.location.href = "/webapp/pages/index.html#/home"; 需注意的是这两个方法的目标地址是同一个,但是跳转方法里传入的path不一样,前者只用是路由配置里path,或者是完整的路径。