angular学习之ngRoute路由机制
ngroute简介
路由是angularjs很重要的一环,它可以把你项目的页面串联起来,构成一个项目,常用的路由有ngroute和ui-route,我这里先讲ngroute。ngroute是一个module,提供路由和深层链接所需的服务和指令。
注意一点,和之前的文章不一样,使用ngroute之前你需要引入另外一个js文件angular-route.js:
<script src="script/angular.min.js"></script> <script src="script/angular-route.min.js"></script>
ngroute包含内容如下:
名称 | 类型 | 作用 |
---|---|---|
ngview | directive | 路由的不同模板其实都是插入这个元素里 |
$routeprovider | provider | 路由配置 |
$route | service | 各个路由的url,view,controller |
$routeparams | service | 路由参数 |
使用ngroute的基本流程如下:
- 在需要路由的地方使用ngview来定义视图模板。
- 在module中注入ngroute模块
- 在config中用$routeprovider来对路由进行配置templateurl,controller,resolve。
- 在每个controller中写业务逻辑
- 在controller中可以通过注入$routeparams来获得url上的参数
可以看下下面这个例子
color.html
<!doctype html> <html> <head> <meta charset="uft-8"/> <title></title> </head> <script src="script/angular.min.js"></script> <script src="script/angular-route.min.js"></script> <body ng-app="color"> <p><a href="#/" rel="external nofollow" rel="external nofollow" >main</a></p> <a href="#red" rel="external nofollow" rel="external nofollow" >red</a> <a href="#green" rel="external nofollow" rel="external nofollow" >green</a> <div ng-view></div> </body> <script> var app = angular.module("color", ["ngroute"]); app.config(function ($routeprovider) { $routeprovider .when("/", { templateurl: "main.html", controller: 'maincontroller' }) .when("/red", { templateurl: "red.html", controller: 'redcontroller' }) .when("/green", { templateurl: "green.html", controller: 'greencontroller' }) .otherwise('/'); }); app.controller('maincontroller',['$scope',function maincontroller($scope){ $scope.message='this is main page'; }]); app.controller('redcontroller',['$scope',function maincontroller($scope){ $scope.message='this is red page'; }]); app.controller('greencontroller',['$scope',function maincontroller($scope){ $scope.message='this is green page'; }]); </script> </html>
red.html (其他页面类似,就不重复了)
<div style="background: red"> {{message}} </div>
例子很简单,我们就只讲下路由的配置:
- 使用$routeprovider.when来配置路由的关系,方法接受两个参数,第一个参数是url的路径,第二个参数是配置url对应的templateurl和controller。
- $routeprovider.otherwise方法相当于default。
路由模块化
可能你已经注意到了上面的都写在一起,如果项目越来越大,会不会很头疼,那么是不是可以把它模块化,每个模块都有直接的module,controller,config等。模块依赖的技术我们之前的module那篇文章已经讲过,那么就来看下带有路由的情况下,怎么模块化。
color.html:
<!doctype html> <html> <head> <meta charset="uft-8"/> <title></title> </head> <script src="script/angular.min.js"></script> <script src="script/angular-route.min.js"></script> <script src="red.js"></script> <script src="green.js"></script> <script src="main.js"></script> <body ng-app="color"> <p><a href="#/" rel="external nofollow" rel="external nofollow" >main</a></p> <a href="#red" rel="external nofollow" rel="external nofollow" >red</a> <a href="#green" rel="external nofollow" rel="external nofollow" >green</a> <div ng-view></div> </body> <script> var app = angular.module("color", ["ngroute","module.red","module.main","module.green"]); app.config(function ($routeprovider) { $routeprovider.otherwise('/'); }); </script> </html>
可以看到我们的color.html文件是不是很简洁,config的路由配置里只有一行$routeprovider.otherwise方法,但是module却注入了除ngroute外的三个module:”module.red”,”module.main”,”module.green”,这其实是把path对应的路由提取成模块,使用了专门的js来处理它们,看起来和他们对应的模板相对应,我们来看下red.html对应的模块js:
red.js
angular.module('module.red', ['ngroute']) .config([ '$routeprovider', function ($routeprovider) { $routeprovider.when('/red', { templateurl: 'red.html', controller: 'redcontroller' }); } ]) .controller('redcontroller', [ '$scope', function ($scope) { $scope.color='red'; $scope.message = 'this is red page'; } ]);
路由的参数
那么路由怎么将参数传入到模板页呢?我们把上面的例子改造一下,通过例子来讲解:
main.js
angular.module('module.main', ['ngroute']) .config([ '$routeprovider', function ($routeprovider) { $routeprovider .when('/', { templateurl: 'main.html', controller: 'maincontroller' }); } ]) .controller('maincontroller', [ '$scope', function ($scope) { $scope.message = 'this is main page'; $scope.colors=['blue','yellow','pink']; } ]);
这里初始化了一个colors的数组,作为要传递的数据。
main.html
{{message}} <br> <ul> <li ng-repeat="color in colors"> <a href="#/color/{{color}}" rel="external nofollow" >{{color}}</a> </li> </ul>
通过ng-repeat循环创建a链接,数组的元素通过链接传入。
colorid.js
angular.module('module.colorid', ['ngroute']) .config([ '$routeprovider', function ($routeprovider) { $routeprovider .when('/color/:colorid', { templateurl: 'colorid.html', controller: 'coloridcontroller' }); } ]) .controller('coloridcontroller', [ '$scope','$routeparams', function ($scope,$routeparams) { $scope.color = $routeparams.colorid; $scope.message = 'this is ' +$routeparams.colorid +' page'; } ]);
这里定义了一个colorid的模块,通过:colorid来匹配传入的参数,这里匹配到的是数组中的元素。例如/color/blue,那么匹配到的就是blue。
colorid.html
<div style="background: {{color}}"> {{message}} </div>
最后在colorid上呈现出来。
如果是多个参数可以直接一一接到后面比如/color/:colorid/:year/:month/:day,和后面的参数也一一匹配,如/color/pink/2017/3/13。
支持*号:/color/:color/largecode/:largecode*/edit匹配/color/brown/largecode/code/with/slashes/edit的话,color将会匹配到brown,largecode将匹配到code/with/slashes。
支持?号:/color/:color/largecode/:largecode?/edit可以匹配匹配/color/brown/largecode/code/edit,largecode将会匹配到code。
/color/:color/largecode/:largecode?/edit可以匹配匹配/color/brown/largecode/edit,largecode将会匹配到空值。
路由中的resolve
一个最常见的情景,页面跳转时要加载一些数据。有两种方式可以做到:
- 页面跳转后加载,通过controller去控制数据的加载,如果时间较长则显示一个loading的界面,数据请求成功后再替换成数据界面
- 页面跳转前加载,通过路由的resolve去配置。
个人更喜欢跳转后加载的方式,因为更为友好,所以对resolve不太感冒,但我们还是讲下resolve。
resolve是一个map对象:
- map的key是可以注入到controller的可选的依赖项,如果resolve其中依赖项的返回值是promise,那么在controller初始化之前,路由会一直等待直到所有的promise都已经resolved或者其中的一个被rejected。如果所有的promise都成功resolved,这些依赖项将可以注入到controller中并同时触发$routechangesuccess事件,如果其中的一个promise是rejected,那么将会触发$routechangeerror事件,并中止路由切换。
- map的value如果是个字符串,那么它会是一个service的别名。如果是一个函数,他的返回值可以被当做依赖注入 到controller中,如果返回值是一个promise,在注入之前必须是resolved的。注意这时候ngroute.$routeparams还不可用,如果需要使用参数则需要使用$route.current.params。
看下例子:
news.html
<html> <head> <meta charset="uft-8"/> <title></title> </head> <script src="script/angular.min.js"></script> <script src="script/angular-route.min.js"></script> <body ng-app="ngst-news"> <div ng-controller="maincontroller"> <ul> <li ng-repeat="news in newsaarry"> <a href="#/newsdetail/{{news.id}}" rel="external nofollow" >{{news.title}}</a> </li> </ul> <div ng-view></div> </div> </body> <script src="news.js" charset="utf-8"></script> <script src="newsdetail.js" charset="utf-8"></script> </html>
news.js
var news = angular.module("ngst-news", ["ngst-newsdetail"]); news.controller("maincontroller", ["$scope", function ($scope) { $scope.newsaarry = [{"id": "1", "title": "辽宁人大副主任王阳 浙江宁波市长卢子跃被免职"}, {"id": "2", "title": "今冬小雨缤纷,荔枝园地湿润壮旺荔枝果树,下刀环剥最狠"}, {"id": "3", "title": "百度任原搜索渠道总经理顾国栋为市场执行总监"}]; }]);
news页面是一个新闻列表,在列表下面有个ng-view,点击新闻列表链接下面的ng-view进行路由切换。
newsdetails.html
{{message}}
newsdetails.js
var news = angular.module("ngst-newsdetail", ['ngroute']); news.config(["$routeprovider", function ($routeprovider) { $routeprovider.when("/newsdetail/:newsid", { templateurl: 'newsdetail.html', controller: 'newsdetailcontroller', resolve: { content: ['$q', '$timeout', "$route", function ($q, $timeout, $route) { var deferred = $q.defer(); $timeout(function () { deferred.resolve('新闻详情 id=' + $route.current.params.newsid); }, 1000); return deferred.promise; }] } }); }]) .controller("newsdetailcontroller", ['$scope', 'content', function ($scope, content) { $scope.message = content; }]);
这里使用$route.current.params来获得参数
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。