一个应用是由若个视图组合而成的,根据不同的业务逻辑展示给用户不同的视图,路由则是实现这一功能的关键。在了解之前我们首先要知道一个概念,就是什么是单页面应用?
单页面应用SPA
SPA(Single Page Application)指的是通单一页面展示所有功能,通过Ajax动态获取数据然后进行实时渲染,结合CSS3动画模仿原生App交互,然后再进行打包(使用工具把Web应用包一个壳,这个壳本质上是浏览器)变成一个“原生”应用。
在PC端也有很多的应用,通常情况下使用Ajax异步请求数据,然后实现内容局部刷新,局部刷新的本质是动态生成DOM,新生成的DOM元素并没有真实存在于文档中,所以当再次刷新页面时新添加的DOM元素会“丢失”,通过单页面应可以很好的解决这个问题。
路由
在后端开发中通过URL地址可以实现页面(视图)的切换,但是AngularJS是一个纯前端MVC框架,在开发单页面应用时,所有功能都在同一页面完成,所以无需切换URL地址(即不允许产生跳转),但Web应用中又经常通过链接(a标签)来更新页面(视图),当点击链接时还要阻止其向服务器发起请求,通过锚点(页内跳转)可以实现这一点。
实现单页面应用需要具备:
a、只有一页面
b、链接使用锚点
//单页面锚点应用的原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--
1:之前使用锚点,只是让锚点调到页面上面对应的某个位置.
//我们有一个事件,监听锚点的改变
//锚点的事件发生了改变就会触发这个事件。
//这个事件叫做 onhashchange hash 值发生改变的时候触发.
-->
<nav>
<li><a href="#/login">登录</a></li>
<li><a href="#/register">注册</a></li>
<li><a href="#/home">首页</a></li>
</nav>
<div class="message">
</div>
<script>
window.onhashchange=function(){
//console.log("锚点发生改变了。");
//锚点的值发生了改变之后,我可以获取到锚点的值
//console.log(window.location.hash);
//hash 就是锚点的值,我们要根据这个值去获取对应的数据.
var hash=window.location.hash;
//截取#
hash=hash.substring(1,hash.length);
//我需要根据这个hash 值去请求对应的页面.
console.log(hash);
var url="";
if(hash=="/login"){
url="login.html";
}else if(hash=="/register"){
url="register.html";
}else if(hash=="/home"){
url="home.html";
}
var xhr=new XMLHttpRequest();
xhr.open("get",url);
xhr.send(null);
xhr.onreadystatechange=function(){
if(xhr.readyState==4 && xhr.status==200){
var data=xhr.responseText;
document.querySelector(".message").innerHTML=data;
}
}
}
</script>
</body>
</html>
通过上面的例子发现在单一页面中可以能过hashchange事件监听到锚点的变化,进而可以实现为不同的锚点准不同的视图,单页面应用就是基于这一原理实现的。
AngularJS对这一实现原理进行了封装,将锚点的变化封装成路由(Route),这是与后端路由的根本区别。
在1.2版前路由功能是包含在AngularJS核心代码当中,之后的版本将路由功能独立成一个模块,下载angular-route.js
使用
1、引入angular-route.js
//AngularJs的核心框架
<script src="angular.min.js"></script>
//AngularJs的路由模块
<script src="angular-route.js"></script>
2、实例化模块时,当成依赖传进去,依赖模块叫ngRoute
//作为依赖传入
var App=angular.module("app",["ngRoute"]);
3、配置路由模块
//通过routeProvider
App.config(["$routeProvider",function($routeProvider){
//路由配置
$routeProvider.when("/index",{
//templateUrl:'index.html'也可以是路径
template:'首页',
//如果需要js控制,可以绑定到控制器
controller:'indexController'
})
}])
4、布局模板
通过ng-view指令布局模板,路由匹配的视图会被加载渲染到些区域。
//视图会被加载渲染到此处
<div ng-view></div>
路由参数
1、提供两个方法匹配路由,分别是when和otherwise,when方法需要两个参数,otherwise方法做为when方法的补充只需要一个参数,其中when方法可以被多次调用。
2、第1个参数是一个字符串,代表当前URL中的hash值。
3、第2个参数是一个对象,配置当前路由的参数,如视图、控制器等。
a、template 字符串形式的视图模板
b、templateUrl 引入外部视图模板
c、controller 视图模板所属的控制器
d、redirectTo跳转到其它路由
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="libs/angular.min.js"></script>
<!--我还需要引入路由模块-->
<script src="libs/angular-route.js"></script>
<script>
//是否依赖其他的模块 ngRoute 路由模块的名字,固定的
var App=angular.module("app",["ngRoute"]);
//我现在肯定要根据锚点去配置路由. $routeProvider
//config 的方法可以使用实现配置
// $routeProvider 去进行配置.
//$routeProvider 有一些方法可以让我们去进行配置.
//when 当
App.config(["$routeProvider",function($routeProvider){
$routeProvider.when("/login",{
//我要出现什么样的视图
template:"我叫做登录页面"
}).when("/register",{
template:"我叫做注册页面"
}).when("/home",{
template:"我是首页"
}).when("/cart",{
//template:"我是购物车",
templateUrl:"cart.html"
});
}]);
</script>
</head>
<body ng-app="app">
<nav>
<li><a href="#/login">登录</a></li>
<li><a href="#/register">注册</a></li>
<li><a href="#/home">首页</a></li>
<li><a href="#/cart">购物车</a></li>
</nav>
<!--angular 的指令 ,数据展示到对应的这个位置.-->
<div ng-view>
</div>
</body>
</html>
4、获取参数,在控制中注入$routeParams可以获取传递的参数
//得到的结果为{id : 10}
.when('/index/:id',{//路由规则
template:" Index Page",
controller:"contr"
})
App.controller("contr",["$routeParams",function($routeParams){
console.log($routeParams);
}])
关于单页面路由的知识我大致总结到这里了,希望对大家有点帮助。