第六章 路由与多视图

在AngularJS应用中,我们可以把一个完整的HTML页面拆分成多个视图,每个视图实际上就是一段HTML片段,路由机制就是在每个视图和URL之间建立映射关系,当通过AngularJS路由API访问URL时,页面中能够加载对应的视图内容

一、创建多视图应用
1.使用$routeProvider创建映射
1.1. $routeProvider 是AngularJS的内置对象,该对象用于创建路由映射,提供了一个 when(path,route) 方法和 otherwise(params) 方法,能够帮助我们将控制器、视图模板、URL关联起来
when(path,route)
(1). path :string类型,路由路径(和$location.path相对应),如果$location.path路
径后有多余的"/"或者缺少"/",路由依然能匹配,并且$location.path会依据路由定义
删除多余的"/"或者增加"/"。除此之外,path中还可以使用占位符,需要使用":"分隔,
例如:/ShowOrders:Num
(2). route :Object类型,用于配置映射信息,具有以下属性
a. controller :{string|function}类型,用于指定控制器名称或控制器构造方法
b. controllerAs :string类型,通过控制器标识符名称引用控制器
c. template :{string|function}类型,用于指定视图模板,也可以是一个返回
HTML模板内容的方法
d. templateUrl :string类型,作用和template属性相同,不同的是,它用于指
定视图模板文件路径
e. resolve :Object类型,用于指定注入控制器中的内容
otherwise(params) 该方法接收一个string类型的参数,用于匹配路由中未定义的
URL
1.2.模块实例的 config() 方法会在模块加载时被执行, 主要用于对服务进行配置
1.3.AngularJS的路由模块作为一个单独的模块,模块名称为 ngRoute ,如果在自定义模块中使用,需要引入angular-route.js文件,并在声明Angular模块时添加 ngRoute 模块依赖
1.4. ng-view 是AngularJS的一个内置指令,用于定义一个视口来加载创建的视图内容
,使用形式有:<div ng-view ></div>
< ng-view ></ ng-view > (IE不兼容)
<div class=" ng-view "></div>
------------------------------------------------angular/js/app.js----------------------------------------------
var routeModule=angular. module ("routeModule",[' ngRoute ']);
routeModule. controller ("AddOrderController",function($scope){});
routeModule. controller ("ShowOrderController",function($scope){});
routeModule. config ([' $routeProvider ',
function( $routeProvider ){
$routeProvider .
when ('/addOrder',{
templateUrl :'templates/add-order.html',
controller :'AddOrderController'
}).
when ('/showOrders',{
templateUrl :'templates/show-orders.html',
controller :'ShowOrderController'
}).
otherwise ({
redirectTo :'/addOrder'
});
}]);
-------------------------------------angular/templates/add-order.html-----------------------------------
<div>
<h3>新增页面</h3>
</div>
-----------------------------------angular/templates/show-orders.html----------------------------------
<div>
<h3>展示页面</h3>
</div>
-----------------------------------------------angular/index.html---------------------------------------------
<!DOCTYPE html>
<html ng-app ="routeModule">
<head>
<meta charset="utf-8">
<title>angularJS</title>
<link rel="stylesheet" type="text/css" href="bootstrap/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css"
href="bootstrap/bootstrap-theme.min.css"/>
<script type="text/javascript" src="angularjs/angular.min.js"></script>
<script type="text/javascript" src="angularjs/angular-route.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<style type="text/css">
.mainDiv{
margin:25px 50px 75px 100px;
}
</style>
</head>
<body>
<div class="mainDiv">
<ul class="nav nav-tabs">
<li>
<a href="#/showOrders">
<span class="glyphicon glyphicon-th-list"></span>订单列表
</a>
</li>
<li>
<a href="#/addOrder">
<span class="glyphicon glyphicon-plus"></span>新增订单
</a>
</li>
</ul>
< ng-view ></ ng-view >
</div>
</body>
</html>
--------------------------------------------------------------------------------------------------------------------

二、通过URL向控制器传递参数
在路由定义时,可以在URL中增加一个参数orderId,用冒号隔开
为了获取URL中传递的参数,需要在控制器中注入 $routeParams 服务,通过 $routeParams .orderId来获取
------------------------------------------------angular/js/app.js----------------------------------------------
var routeModule=angular.module("app",[' ngRoute ']);
routeModule.config([' $routeProvider ',
function( $routeProvider ){
$routeProvider .
when('/showOrder/: orderId ',{
templateUrl :'templates/order-details.html',
controller :'ShowOrderController'
})
}]);
routeModule.controller('ShowOrderController',function( $scope , $routeParams ){
$scope .order_id= $routeParams . orderId ;
});
-----------------------------------angular/templates/orders-details.html--------------------------------
<h2>订号单 #{{order_id}}</h2>
此处为订单明细... <b>#{{order_id}}</b>
-----------------------------------------------angular/index.html---------------------------------------------
<!DOCTYPE html>
<html ng-app ="routeModule">
<head>
<meta charset="utf-8">
<title>angularJS</title>
<link rel="stylesheet" type="text/css" href="bootstrap/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css"
href="bootstrap/bootstrap-theme.min.css"/>
<script type="text/javascript" src="angularjs/angular.min.js"></script>
<script type="text/javascript" src="angularjs/angular-route.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<style type="text/css">
.mainDiv{
margin:25px 50px 75px 100px;
}
</style>
</head>
<body>
<div class="mainDiv">
<ul class="nav nav-tabs">
<li>
<a href="#">
<span class="glyphicon glyphicon-th-list"></span>
订单列表
</a>
</li>
</ul>
<div>
<table class="table">
<thead>
<tr>
<th>订单号</th>
<th>商品名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr class="success">
<td>1102</td>
<td>笔记本电脑</td>
<td><a href="# /showOrder/1102 ">查看明细</a></td>
</tr>
<tr class="info">
<td>4531</td>
<td>移动硬盘</td>
<td><a href="# /showOrder/4531 ">查看明细</a></td>
</tr>
</tbody>
</table>
</div>
<ng-view></ng-view>
</div>
</body>
</html>
--------------------------------------------------------------------------------------------------------------------

三、ng-template指令的使用
有时,视图内容比较少,希望把不同的视图继承到同一个页面中,或者要开发一个反页面应用(SPA),就可以使用 ng-template 指令来实现
注意, templateUrl 为script标签的id
--------------------------------------------------------------------------------------------------------------------
<!DOCTYPE html>
<html ng-app ="templateModule">
<head>
<title>template</title>
<script type="text/javascript" src="angular-1.5.5/angular.min.js"></script>
<script type="text/javascript" src="angular-1.5.5/angular-route.min.js"></script>
</head>
<body>
<div>
<a href="#/view1">view1</a>
<a href="#/view2">view2</a>
</div>
<div ng-view ></div>
<script type="text/ ng-template " id=" /viewId1 ">view1</script>
<script type="text/ ng-template " id=" /viewId2 ">view2</script>
<script type="text/javascript">
var templateModule=angular. module ('templateModule',[' ngRoute ']);
templateModule. config ([' $routeProvider ',
function( $routeProvider ){
$routeProvider .
when ('/view1',{
templateUrl :' /viewId1 '
}).
when ('/view2',{
templateUrl :' /viewId2 '
});
}]);
</script>
</body>
</html>
--------------------------------------------------------------------------------------------------------------------

四、$location服务
$location 服务是AngularJS中和浏览器地址栏URL相关的一个内置服务,始终和浏览器地址栏URL保持同步状态,浏览器地址栏发生改变时, $location 服务会实时更新。使用 $location 服务可以获取地址栏URL,或者对地址栏URL进行修改,以达到访问不同路由的效果。其中一些属性只能获取而无法修改,如host、protocol、port等,有些是可以修改的,如path、search、hash等
以http://foo.com:8080/bar?bar=23#baz为例,URL主要由一下几个部分构成
(1).Protocal:协议名,通过 $location . protocal() 获取,会返回字符串http
(2).Host:主机名,通过 $location . host() 获取,返回foo.com
(3).Port:端口号,通过 $location . port() 获取,返回8080
(4).Path:AngularJs的 $location 服务支持两种URL模式,即HTML5模式和Hashbang
模式(默认)。HTML5模式下, path 为端口之后,请求参数之前的部分,即/bar;
Hashbang模式下,path为第一个#后的内容,即baz。 $location 服务默认采用
Hashbang模式,可以通过 $locationProvider 对象进行模式设置
--------------------------------------------------------------------------------------------------------------------
routeModel. config ([' $locationProvider ',
function( $locationProvider ){
$locationProvider . html5Mode (true);
}
]);
--------------------------------------------------------------------------------------------------------------------
(5).Search:Search可以认为是URL中的请求参数,可以通过 $location . search() 获取
或设置:$location.search({key1:value1,key2:value2})
(6).Hash:用于把当前浏览器窗口定位于HTML的某一部位,通过 $location . hash()
取或设置

五、$location实现多视图切换
--------------------------------------------------------------------------------------------------------------------
<!DOCTYPE html>
<html ng-app ="app">
<head>
<meta charset="utf-8">
<title>angularjs</title>
<script type="text/javascript" src="angular-1.5.5/angular.min.js"></script>
<script type="text/javascript" src="angular-1.5.5/angular-route.min.js"></script>
</head>
<body>
<div ng-controller =" ViewController ">
<button ng-click ="changeView1()">view1</button>
<button ng-click ="changeView2()">view2</button>
</div>
<div ng-view ></div>
<script type="text/javascript">
var appAngular= angular . module ("app",[' ngRoute ']);
appAngular.config([' $routeProvider ',function( $routeProvider ){
$routeProvider .
when ("/view1",{
templateUrl :"/viewId1"
}).
when ("/view2",{
templateUrl :"/viewId2"
});
}]);
appAngular. controller (" ViewController ",function( $scope , $location ){
$scope .changeView1=function(){
$location . path ('/view1');
}
$scope .changeView2=function(){
$location . path ('/view2');
}
});
</script>
<script type="text/ ng-template " id="/viewId1">view1</script>
<script type="text/ ng-template " id="/viewId2">view2</script>
</body>
</html>
--------------------------------------------------------------------------------------------------------------------

六、路由事件
1.$location相关事件
$locationChangeStart :该事件会在调用 $location 服务的一些方法改变浏览器地址栏之前触发,并会被传递到 $rootScope 作用域中
$locationChangeSuccess :该事件在调用 $location 服务改变浏览器地址栏URL后触发,但如果监听 $locationChangeStart 事件并调用 preventDefault() 方法阻止事件的传播后,该事件将不会被触发
2.$route相关事件
$routeChangeStart :该事件会在AngularJS开始改变路由时触发,也会被传递到 $routeScope 作用域中
$routeChangeSuccess :该事件会在路由改变成功时触发,AngularJS的 ng-view 指令会监听该事件,接收到该事件时会实例化相应的控制器并渲染视图
$routeChangeError :路由切换异常时触发,该事件同样会传递到 $rootScope 作用域

七、ng-include指令
ng-include 指令用于页面中包含其他HTML文件,可以通过属性形式或者作为HTML元素使用:<div ng-include =" ' ./common/navbar.html ' "></div>
< ng-include src=" ' ./common/navbar.html ' "></ ng-include >
--------------------------------------------common/navbar.html--------------------------------------------
<div>
<h3>这里是导航</h3>
</div>
---------------------------------------------common/footer.html--------------------------------------------
<div>
<h3>这里是页脚</h3>
</div>
----------------------------------------------------index.html---------------------------------------------------
<!DOCTYPE html>
<html ng-app >
<head>
<meta charset="utf-8">
<title>index</title>
<script type="text/javascript" src="./angular-1.5.5/angular.min.js"></script>
</head>
<body>
<div ng-include ="'./common/navbar.html'"></div>
<div>body</div>
<div ng-include ="'./common/footer.html'"> </div>
</body>
</html>
--------------------------------------------------------------------------------------------------------------------
注意,在目前的HTML规范中还不支持HTML包含功能(火狐可以,谷歌不行不知道是不是因为这个)

八、UI Router框架使用
UI Router 是基于AngularJS的,用于编写单页面应用的路由框架,支持多试图嵌套和多个命名视图
AngularJS的 ngRouter 模块可以实现多视图切换效果,但有一些局限性-多视图之间不能进行嵌套,例如,通过 ng-view 指令加载了一个控制面板页面后,如果想在控制面板中添加一些子视图, ngRoute 模块就不支持,因此需要使用 UI Router 框架
1.UI Router使用案例
(1).下载并引入angular-ui-router.js文件
(2).在自定义angular模块中添加 ui.route 模块依赖
(3). $stateProvider $urlRouteProvider 是UI Route框架提供的两个Provider对象,要使用这两个对象,首先需要在自定义模块总添加 ui.route 依赖
(4).通过模块实例的 config() 方法进行配置
a.调用 $urlRouteProvider otherwise() 方法指定当我们请求不存在的状态名时跳
转到的页面,该方法接收一个string类型,指定视图页面
b.调用 $stateProvider state() 方法定义状态,该方法接收两个参数,第一个参数
为状态名,第二个参数是一个对象,用于描述状态信息,其中 url 属性为状态对应的
URL, templateUrl 属性指定路由切换时候加载的HTML视图, controller 属性指定当前
视图对应的控制器
(6).主页面中使用UI Route内置的 ui-sref 指令指定一个状态名称
--------------------------------------------common/home.html--------------------------------------------
<h4>我的书籍</h4>
<ul class="nav">
<li ng-repeat ="book in books">
<span class="glyphicon glyphicon-book"/>
&nbsp;<a href="#"> {{book}} </a>
</li>
</ul>
--------------------------------------------common/about.html--------------------------------------------
<h4>关于页面</h4>
姓名: {{name}}
--------------------------------------------common/contact.html--------------------------------------------
<h4>联系我:</h4>
<a href="mailto:caishunfeng@gmail.com">
caishunfeng@gmai.com
</a>
--------------------------------------------------------app.js----------------------------------------------------
var appAngular=angular. module ("app",[" ui.router "]);
appAngular. config (function( $stateProvider , $urlRouterProvider ){
$urlRouterProvider . otherwise ("/");
$stateProvider . state ("home",{
url :"/home",
templateUrl :"common/home.html",
controller :function( $scope ){
$scope .books=['红楼梦','金瓶梅','石头记'];
}
});
$stateProvider . state ("about",{
url :"/about",
templateUrl :"common/about.html",
controller :function($scope){
$scope .name="蔡舜烽";
}
});
$stateProvider . state ("contact",{
url :"/contact",
templateUrl :"common/contact.html"
});
});
--------------------------------------------------index.html-----------------------------------------------------
<!DOCTYPE html>
<html ng-app ="app">
<head>
<meta charset="utf-8">
<title>index</title>
<link rel="stylesheet" type="text/css"
href="bootstrap-3.3.7-dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css"
href="bootstrap-3.3.7-dist/css/bootstrap-theme.min.css">
<script type="text/javascript" src="angular-1.5.5/angular.min.js"></script>
<script type="text/javascript" src="angular-extend/angular-ui-router.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
<div>
<ul class="breadcrumb">
<li><a ui-sref ="home">首页</a></li>
<li><a ui-sref ="about">关于</a></li>
<li><a ui-sref ="contact">联系</a></li>
</ul>
</div>
<div ui-view ></div>
<div class="footer navbar-fixed-bottom">
<div class="container">
@Jiang Rongbo,Blog:
<a href="http://blog.csdn.net/rongbo_j">
http://blog.csdn.net/rongbo_j
</a>
</div>
</div>
</body>
</html>
--------------------------------------------------------------------------------------------------------------------








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值