angular学习之ngRoute路由机制


Posted in Javascript onApril 12, 2017

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的基本流程如下:

  1. 在需要路由的地方使用ngView来定义视图模板。
  2. 在module中注入ngRoute模块
  3. 在config中用$routeProvider来对路由进行配置templateUrl,controller,resolve。
  4. 在每个controller中写业务逻辑
  5. 在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>

例子很简单,我们就只讲下路由的配置:

  1. 使用$routeProvider.when来配置路由的关系,方法接受两个参数,第一个参数是url的路径,第二个参数是配置url对应的templateUrl和controller。
  2. $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

一个最常见的情景,页面跳转时要加载一些数据。有两种方式可以做到:

  1. 页面跳转后加载,通过controller去控制数据的加载,如果时间较长则显示一个loading的界面,数据请求成功后再替换成数据界面
  2. 页面跳转前加载,通过路由的resolve去配置。

个人更喜欢跳转后加载的方式,因为更为友好,所以对resolve不太感冒,但我们还是讲下resolve。

resolve是一个map对象:

  1. map的key是可以注入到controller的可选的依赖项,如果resolve其中依赖项的返回值是promise,那么在controller初始化之前,路由会一直等待直到所有的promise都已经resolved或者其中的一个被rejected。如果所有的promise都成功resolved,这些依赖项将可以注入到controller中并同时触发$routeChangeSuccess事件,如果其中的一个promise是rejected,那么将会触发$routeChangeError事件,并中止路由切换。
  2. 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来获得参数

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
showModelessDialog()使用详解
Sep 07 Javascript
document.compatMode介绍
May 21 Javascript
js完美的div拖拽实例代码
Jan 22 Javascript
js中的eval()函数把含有转义字符的字符串转换成Object对象的方法
Dec 02 Javascript
javascript稀疏数组(sparse array)和密集数组用法分析
Dec 28 Javascript
用jQuery实现圆点图片轮播效果
Mar 19 Javascript
JS实现移动端实时监听输入框变化的实例代码
Apr 12 Javascript
vue中七牛插件使用的实例代码
Jul 28 Javascript
详解vue-cli中模拟数据的两种方法
Jul 03 Javascript
layui实现文件或图片上传记录
Aug 28 Javascript
VueCli3构建TS项目的方法步骤
Nov 07 Javascript
JavaScript设计模型Iterator实例解析
Jan 22 Javascript
Node.js发送HTTP客户端请求并显示响应结果的方法示例
Apr 12 #Javascript
微信小程序登录态控制深入分析
Apr 12 #Javascript
JavaScript数据结构之二叉查找树的定义与表示方法
Apr 12 #Javascript
微信小程序微信支付接入开发实例详解
Apr 12 #Javascript
JavaScript数据结构之广义表的定义与表示方法详解
Apr 12 #Javascript
JavaScript数据结构之数组的表示方法示例
Apr 12 #Javascript
easyui-edatagrid.js实现回车键结束编辑功能的实例
Apr 12 #Javascript
You might like
造就帕卡马拉的帕卡斯是怎么被发现的
2021/03/03 咖啡文化
PHP JSON 数据解析代码
2010/05/26 PHP
php实现水仙花数示例分享
2014/04/03 PHP
yii框架builder、update、delete使用方法
2014/04/30 PHP
PHP安全下载文件的方法
2016/04/07 PHP
PHP实现上传图片到 zimg 服务器
2016/10/19 PHP
基于laravel-admin 后台 列表标签背景的使用方法
2019/10/03 PHP
在JavaScript中实现命名空间
2006/11/23 Javascript
轻量级 JS ToolTip提示效果
2010/07/20 Javascript
jQuery中:hidden选择器用法实例
2014/12/30 Javascript
jQuery创建DOM元素实例解析
2015/01/19 Javascript
JavaScript前端开发之实现二进制读写操作
2015/11/04 Javascript
JavaScript从0开始构思表情插件
2016/07/26 Javascript
JS+CSS3模拟溢出滚动效果
2016/08/12 Javascript
js实现数组和对象的深浅拷贝
2017/09/30 Javascript
基于Two.js实现星球环绕动画效果的示例
2017/11/06 Javascript
Vue登录主页动态背景短视频制作
2019/09/21 Javascript
浅谈Vue3.0新版API之composition-api入坑指南
2020/04/30 Javascript
vue 页面回退mounted函数不执行的解决方案
2020/07/26 Javascript
element 动态合并表格的步骤
2020/12/31 Javascript
Python实现定时自动关闭的tkinter窗口方法
2019/02/16 Python
如何爬取通过ajax加载数据的网站
2019/08/15 Python
Python中输入和输出(打印)数据实例方法
2019/10/13 Python
python 实现从高分辨图像上抠取图像块
2020/01/02 Python
python 对任意数据和曲线进行拟合并求出函数表达式的三种解决方案
2020/02/18 Python
pycharm如何实现跨目录调用文件
2020/02/28 Python
详解用Python进行时间序列预测的7种方法
2020/03/13 Python
萌新HTML5 入门指南(二)
2020/11/09 HTML / CSS
美国卡车、吉普车和SUV零件网站:4 Wheel Parts
2016/11/24 全球购物
超市实习总结自我鉴定
2013/09/19 职场文书
市场营销专业求职信
2014/06/17 职场文书
北京故宫的导游词
2015/01/31 职场文书
绿里奇迹观后感
2015/06/15 职场文书
文书工作总结(范文)
2019/07/11 职场文书
浅析python中特殊文件和特殊函数
2022/02/24 Python
为什么MySQL8新特性会修改自增主键属性
2022/04/18 MySQL