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 相关文章推荐
ext 代码生成器
Aug 07 Javascript
Riot.js 快速的JavaScript单元测试框架
Nov 09 Javascript
jQuery中使用data()方法读取HTML5自定义属性data-*实例
Apr 11 Javascript
JavaScript+html5 canvas制作的圆中圆效果实例
Jan 27 Javascript
javascript创建cookie、读取cookie
Mar 31 Javascript
JavaScript中利用构造器函数模拟类的方法
Feb 16 Javascript
详解vue.js+UEditor集成 [前后端分离项目]
Jul 07 Javascript
vue的基本用法与常见指令
Aug 15 Javascript
详解如何提升JSON.stringify()的性能
Jun 12 Javascript
vue实现全屏滚动效果(非fullpage.js)
Mar 07 Javascript
详解js中的几种常用设计模式
Jul 16 Javascript
Vue的生命周期一起来看看
Feb 24 Vue.js
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
其他功能
2006/10/09 PHP
PHP+MySQL 手工注入语句大全 推荐
2009/10/30 PHP
php学习之 数组声明
2011/06/09 PHP
第五章 php数组操作
2011/12/30 PHP
PHPMYADMIN导入数据最大为2M的解决方法
2012/04/23 PHP
Fine Uploader文件上传组件应用介绍
2013/01/06 PHP
修改destoon会员公司的伪静态中的com目录的方法
2014/08/21 PHP
js不能获取隐藏的div的宽度只能先显示后获取
2014/09/04 Javascript
EasyUI实现二级页面的内容勾选的方法
2015/03/01 Javascript
手机图片预览插件photoswipe.js使用总结
2016/08/25 Javascript
JavaScript函数节流的两种写法
2017/04/07 Javascript
d3.js实现立体柱图的方法详解
2017/04/28 Javascript
用Nodejs搭建服务器访问html、css、JS等静态资源文件
2017/04/28 NodeJs
js 判断一个数字是不是2的n次方幂的实例
2017/11/26 Javascript
angular6.0开发教程之如何安装angular6.0框架
2018/06/29 Javascript
angularjs的单选框+ng-repeat的实现方法
2018/09/12 Javascript
js键盘事件实现人物的行走
2020/01/17 Javascript
JQuery实现折叠式菜单的详细代码
2020/06/03 jQuery
解决vue单页面应用进入页面加载所有 js 的问题
2020/08/12 Javascript
跟老齐学Python之开始真正编程
2014/09/12 Python
Python模拟脉冲星伪信号频率实例代码
2018/01/03 Python
Python if语句知识点用法总结
2018/06/10 Python
Python使用pandas处理CSV文件的实例讲解
2018/06/22 Python
详解关于Django中ORM数据库迁移的配置
2018/10/08 Python
Python传递参数的多种方式(小结)
2019/09/18 Python
使用pygame实现垃圾分类小游戏功能(已获校级二等奖)
2020/07/23 Python
python 用struct模块解决黏包问题
2020/11/07 Python
Python高阶函数与装饰器函数的深入讲解
2020/11/10 Python
采购主管的岗位职责
2013/12/17 职场文书
给实习单位的感谢信
2014/02/01 职场文书
建筑专业毕业生自荐信
2014/05/25 职场文书
2014年民主评议党员个人总结
2014/09/24 职场文书
python opencv常用图形绘制方法(线段、矩形、圆形、椭圆、文本)
2021/04/12 Python
Pytorch实现图像识别之数字识别(附详细注释)
2021/05/11 Python
pandas中对文本类型数据的处理小结
2021/11/01 Python
python flappy bird小游戏分步实现流程
2022/02/15 Python