angular的ngRoute详解
2016.10.30
maotingfeng
angular的ngRoute详解
AngularJS的路由其实是一种纯前端的解决方案。不同于后端的路由,后端的路由是匹配不同的路由,输出不同的内容,浏览器拿到当前路由的内容,直接渲染展示。AngularJS的路由,当请求了这个url,根据其路由匹配规则,来匹配当前的url,然后请求模版,然后把数据结合模版插入到ng-view中去。总结就是,局部刷新体现在url的变更上。url变更,就可以记录到历史中去了,方便用户浏览历史,回退操作。相对于单纯的ajax局部刷新,优点还是很明显的。
实例
文件目录结构:
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <!DOCTYPE html> <html> <head> <title>angular ngRoute测试</title> <script src="http://cdn.bootcss.com/angular.js/1.5.8/angular.min.js"></script> <script src="http://cdn.bootcss.com/angular.js/1.5.8/angular-route.min.js"></script> </head> <body ng-app="routeApp" ng-controller="routeController"> <h1>Angular Route Demo</h1> <div> <a href="#/home">home</a> <a href="#/post">post</a> <a href="#/about">about</a> </div> <hr/> <div ng-view></div> <script src="/js/post.js"></script> <script src="/js/index.js"></script> </body> </html>
|
home.html
about.html
post.html
1 2
| <p>我是post的内容</p> <a href="#/post/19">跳转到id为19号的文章</a>
|
post-id.html
1
| <p>这是post-id中的内容,动态获取到的id参数为:{{post_id}}</p>
|
运行可看到如下界面:
可以看到ng-view
标识的属性元素,被home.html
的内容填充了。
post.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| angular.module( 'Module.Post' , ['ngRoute'] ) .config(['$routeProvider',function($routeProvider){ $routeProvider.when('/post',{ templateUrl: 'post.html' , controller: 'PostController' }).when('/post/:post_id',{ templateUrl: 'post-id.html' , controller: 'PostIdController' }) }]).controller( 'PostController' , [ '$scope' , function( $scope ){ } ] ).controller( 'PostIdController' , [ '$scope' , '$routeParams' , function( $scope , $routeParams ){ $scope.post_id = '$routeParams.post_id = ' + $routeParams.post_id + '。' ; } ] ) ;
|
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| angular.module( 'routeApp' , ['ngRoute','Module.Post'] ) .config(['$routeProvider',function($routeProvider){ $routeProvider.when('/home',{ templateUrl: 'home.html' , controller: 'HomeController' }).when('/about',{ templateUrl: 'about.html' , controller: 'AboutController' , resolve: { longTime: [ '$q' , '$timeout' , function( $q , $timeout ){ var deferred = $q.defer() ; $timeout(function() { deferred.resolve( '耗时3秒的操作完成了' ); } , 3000 ) ; return deferred.promise ; } ] } }).otherwise('/home') }]).controller( 'routeController' , [ '$scope' , function( $scope ){ } ] ).controller( 'HomeController' , [ '$scope' , function( $scope ){ } ] ).controller( 'AboutController' , [ '$scope' , 'longTime' , function( $scope , longTime ){ } ] ) ;
|
需要注意的几点:
- module需要导入ngRoute模块
- $routeProvider的when方法,接收两个参数,第一个参数是路由,第二个参数是路由配置参数。
- otherwise用于默认的路由参数,类似导致404的路由,都会被重定向到这个默认的路由里。
- 推荐
post.js
中的写法,模块化路由,讲相关的路由封装到一个post.js中,然后其它模块导入这个模块。
$routeParams
在post.js
中,我们使用$routeProvider
配置的第二个路由是这样的/post/:post_id
。路由中的/:post_id
其实是一个参数,它将匹配类似/post/001
这种url,其中001就是这个:post_id
的值。我们在路由对应的控制器中,可以通过$routeParams
参数来获取这个url参数。
路由配置中的resolve
在配置路由时,配置resolve
选项。配置resolve
选项意味着,在进入这个路由之前就必须等待resolve
中的数据返回。
一般用于进入某个路由比较耗时,比如新闻标题进入新闻详情,新闻详情页需要ajax请求后台,后台返回数据之前,这个路由其实不应该执行,而是应该等待后台响应数据。这里一个加一个loading gif之类的动画。当ajax完成之后,angular通过注册resolve返回的promise对象的then方法,得知数据已经拿到了,把模版填充到ng-view
中,然后执行对应路由的控制器。整个过程完成
需要注意的是:
- 可以将resolve配置中的键,本例是
AboutController
中的longTime
键,可以将它注入其控制器中,然后就可以拿到后台返回的值了,本例返回的是:'耗时3秒的操作完成了'
。