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="#/">Main</a></p>

<a href="#red">Red</a>
<a href="#green">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="#/">Main</a></p>

<a href="#red">Red</a>
<a href="#green">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}}">{{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}}">{{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来获得参数

时间: 2024-12-28 13:26:00

Angular学习(十六)——ngRoute的相关文章

angular学习笔记(六)

这篇主要讲解非入侵式javascript. 在传统的前端开发中,把js写在html中,称为入侵式的javascript: <span id="select_area" onclick="..." </span> 这种做法由于没有把视图和行为分离,而且不易于维护管理,所以已经被淘汰掉. 但是,angular通过改进,很好的解决了这个问题.称为声明式事件处理器. <!DOCTYPE html> <html ng-app> <

Java编程思想学习(十六) 并发编程

线程是进程中一个任务控制流序列,由于进程的创建和销毁需要销毁大量的资源,而多个线程之间可以共享进程数据,因此多线程是并发编程的基础. 多核心CPU可以真正实现多个任务并行执行,单核心CPU程序其实不是真正的并行运行,而是通过时间片切换来执行,由于时间片切换频繁,使用者感觉程序是在并行运行.单核心CPU中通过时间片切换执行多线程任务时,虽然需要保存线程上下文,但是由于不会被阻塞的线程所阻塞,因此相比单任务还是大大提高了程序运行效率. 1.线程的状态和切换: 线程的7种状态及其切换图如下: 2.多线

java web 学习十六(JSP指令)

一.JSP指令简介 JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指令: page指令 Include指令 taglib指令 JSP指令的基本语法格式:<%@ 指令 属性名="值" %> 例如: 1 <%@ page contentType="text/html;charset=gb2312"%> 如果一个指令有多个属性,

java学习(十六):对象的自定义比较,Comparator和Comparable

通过两个例子实现对象的自定义排序 1.实现Comparator接口. 1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.Comparator; 4 import java.util.List; 5 6 public class StudentComparator implements Comparator<Object> 7 { 8 @Override 9 public int co

Flask 学习 十六 部署

部署流程 manage.py 部署命令 每次安装升级只需运行deploy命令即可完成操作 @manager.command def deploy(): """执行部署任务""" from flask_migrate import upgrade from app.models import Role, User # 把数据库迁移到最新修订版本 upgrade() # 创建用户角色 Role.insert_roles() # 让所有用户都关注此用户

学习十六

4.10/4.11/4.12 lvm讲解 4.13 磁盘故障小案例lvm讲解首先检查一下是否安装lvmlvm的优缺点lvm很方便的去创建和整合分区,但是假如用盘分区出现问题需要恢复文件的时候可能会出现很难恢复的问题 起始lvm 是创建物理分区 创建物理卷,在组建物理卷组 再组建逻辑分区 再格式化 挂载使用要做的准备fdisk 创建三个1G的分区 ID为83为普通分区t更改类型为8e做物理卷 lvm ctrl+u 删除前面错误的内容下面创建物理卷假如查不到命令 可以采用通配的方法来查找命令在此处可

mybatis学习 十六 auto_mapping实现连表查询

只能使用多表联合查询方式. 要求:查询出的列别和属性名相同. 点字符  "."  在 SQL 是关键字符,两侧添加反单引号(Tab键上的一个字符) <select id="selAll" resultType="student"> select t.id `teacher.id`, t.name `teacher.name`, s.id id, s.name name,age,tid from student s LEFT JOIN

spring学习 十六 spring加载属性文件

第一步:创建一个properties文件,以数据库链接作为实例 db.properties jdbc.url=jdbc:mysql://192.168.153.128:3306/mybaties?characterEncoding=utf-8 jdbc.driver=com.mysql.jdbc.Driver jdbc.username=com.mysql.jdbc.Driver jdbc.password=123456 第二步在spring配置文件加入context的约束,并使用<contex

MySQL学习(十六)

MySQL高级部分 触发器 触发器是一类特殊的事务,可以监视某种数据操作(insert/update/delete),并触发相关的操作(insert/update/delete) 触发器创建语法之4要素 1 监视地点table 2 监视事件insert/update/delete 3 触发时间after/before 4 触发事件 查看已有的触发器 show triggers 删除已有的触发器 drop trigger triggerName 创建一个触发器 create trigger t1

前端学习(39)~js学习(十六):数组

数组简介 数组(Array)是属于内置对象,我们可以在MDN网站上查询各种方法. 数组和普通对象的功能类似,也是用来存储一些值的.不同的是: 普通对象是使用字符串作为属性名的,而数组是使用数字来作为索引来操作元素.索引:从0开始的整数就是索引. 数组的存储性能比普通对象要好.在实际开发中我们经常使用数组来存储一些数据,使用频率非常高. 数组中的元素可以是任意的数据类型,也可以是对象,也可以是函数,也可以是数组.数组的元素中,如果存放的是数组,我们就称这种数组为二维数组. 接下来,我们讲一讲数组的