AngularJS 路由机制是由ngRoute模块提供,它容许咱们将视图分解成布局和模板视图,根据url变化动态的将模板视图加载到布局中,从而实现单页面应用的页面跳转功能。html
AngularJS 路由容许咱们经过不一样的 URL 访问不一样的内容。web
经过 AngularJS 能够实现多视图的单页Web应用(single page web application,SPA)。promise
一般咱们的URL形式为 http://cnblogs.com/first/page,但在单页Web应用中 AngularJS 经过 # + 标记 实现,例如:浏览器
http://cnblogs.com/#/first
http://cnblogs.com/#/second
http://cnblogs.com/#/third
当咱们点击以上的任意一个连接时,向服务端请的地址都是同样的 (http:/cnblogs.com/)。 由于 # 号以后的内容在向服务端请求时会被浏览器忽略掉。 因此咱们就须要在客户端实现 # 号后面内容的功能实现。 AngularJS 路由 就经过 # + 标记 帮助咱们区分不一样的逻辑页面并将不一样的页面绑定到对应的控制器上。服务器
01app
<script src="angular-route.min.js"></script> var app = angular.module("myApp",['ngRoute']);
之因此要建立布局模板,是为了告诉AngularJS应该将布局渲染到何处。经过ng-view指令,咱们能够精确的指定模板视图在DOM中的渲染位置。编辑器
<div ng-app="myApp"> <a ng-href="#/bq1">标签1</a> <a ng-href="#/bq2">标签2</a> <a ng-href="#/bq3">标签3</a> <a ng-href="#/bq4">标签4</a> <div ng-view></div> </div>
myBq1.htmlide
<p>这是标签1</p>
myBq2.html函数
<p>这是标签2</p>
myBq3.html布局
<p>这是标签3</p>
myBq4.html
<p>这是标签4</p>
app.config(['$routeProvider',function($routeProvide) { $routeProvide .when('/',{templateUrl:"home.html"}) .when('/music',{templateUrl:"myMusic.html"}) .when('/movie',{templateUrl:"myMovie.html"}) .when('/novel',{templateUrl:"myNovel.html"}) .otherwise({redirectTo:'/'}); }]);
02
若是没有参数,返回当前路径,即#号后的内容;也能够传入字符串,将当前路径修改成字符串的内容,并触发路由变化。
假设当前url:http://localhost:63342/RouteDemo/index.html#/
//返回'/'
$location.path();
//将当前url修改成:http://localhost:63342/RouteDemo/index.html#/music
$locaiton.path('/music');
//返回'/music'
$locaiton.path();
when方法可以接收两个参数,第一个参数是路由路径,这个路径会与$location.path()的值进行匹配,若是没有任何一个when方法匹配到,那么将会执行otherwise方法。第二个参数是配置对象,它的六个属性分别是controller,template,templateUrl,resolve,redirectTo,reloadOnSearch。
//每次路径变为/music触发路由变化时都会执行一次控制器中的内容 app.config(['$routeProvider',function($routeProvide) { $routeProvide.when('/music'{templateUrl:"myMusic.html",controller:"myController"}) }]); app.controller('myController',function($scope) { console.log("123"); });
只有当resolve对象里全部promise对象执行完毕后才会注入到控制器,此时才会发生路由变化,所以能够解决页面闪烁问题(加载页面后才获取到数据去更新视图)。咱们来看看对比,下面这个例子控制器注入的a是自定义的myService服务,注入的b则是从服务器端获取到的数据。
test.html代码以下。
<p>我是测试界面 {{ name }}</p> <div ng-repeat="name in list">{{ name }}</div>
index.html代码以下。
<body ng-app="myApp"> <div ng-app="myApp"> <a ng-href="#/test">测试</a> <div ng-view></div> </div> <script> var app = angular.module("myApp",['ngRoute']); app.value("myService","张三"); app.config(['$routeProvider',function($routeProvide) { $routeProvide .when('/test',{templateUrl:"test.html", controller:function($scope,a,b) { $scope.name = "你好"+a; $scope.list = b.data; }, resolve:{ a:"myService", b:function($http,$timeout) { var promise = $timeout(function() { return $http.get("http://localhost:3000/person"); },3000); return promise; } }}); }]); </script> </body>
若是直接在控制器而不是resolve中请求,则index.html代码以下。
<body ng-app="myApp"> <div ng-app="myApp"> <a ng-href="#/test">测试</a> <div ng-view></div> </div> <script> var app = angular.module("myApp",['ngRoute']); app.value("myService","张三"); app.config(['$routeProvider',function($routeProvide) { $routeProvide .when('/test',{templateUrl:"test.html", controller:function($scope,$http,$timeout,a) { $scope.name = "你好"+a; var promise = $timeout(function() { return $http.get("http://localhost:3000/person"); },3000); promise.then(function(response) { $scope.list = response.data; }); }, resolve:{ a:"myService" }}); }]); </script> </body>
二者效果以下,能够看到写在控制器中的代码不只须要本身处理逻辑(控制器不推荐写太复杂的逻辑)从promise的success function中取得repsonse参数,并且页面加载不一致,服务器获取的数据在得到后才加载,而在resolve中写,只有等promise执行完毕后才会跳转,而后同步加载整个页面。
- redirectTo
值是一个字符串或一个函数,该属性写在otherwise中,表明着在when中找不到相应路径时的重定向。若是是字符串,路径会被替换成该值,若是是函数,它有三个参数,第一个是当前路径的路由参数,第二个是当前路径,第三个当前Url的查询串,路径会被替换成该函数的返回值,替换后都会触发路由变化。
- reloadOnSearch
值是一个布尔值,为true的时候$location.search()发生变化时就会从新加载路由,location.search是从当前URL的?号开始(包括?号)的字符串。
咱们能够在路由参数的前面加上:号,AngularJS会把它解析出来并传递给$routeParams。
下面的例子中咱们将123456传给value,AngularJS把其解析出来,在$routeParams中添加一个名为value的键,值为123456,咱们能够将该服务注入到控制器中使用。
test.html代码以下。
<p>我是测试界面 {{ display }}</p>
<body ng-app="myApp"> <div ng-app="myApp"> <a ng-href="#/test/123456">测试</a> <div ng-view></div> </div> <script> var app = angular.module("myApp",['ngRoute']); app.config(['$routeProvider',function($routeProvide) { $routeProvide .when('/test/:value',{templateUrl:"test.html", controller:function($scope,$routeParams) { $scope.display = $routeParams.value; }}); }]); </script> </body>
$route服务在路由过程当中的每一个阶段都会触发不一样的事件,能够为这些事件设置监听器并作出响应。路由事件都是系统自动从$rootScope广播下去的,咱们最好的作法是在$rootScope中监听,而最佳设置的地方就是run方法,能够保证不会漏掉任何路由变化。
下面是四种不一样的路由事件。
$routeUpdate 在reloadOnSearch属性设置为false的状况下,从新使用某个控制器的实例会广播该事件。