AngularJS 路由机制是由ngRoute模块提供,它允许我们将视图分解成布局和模板视图,根据url变化动态的将模板视图加载到布局中,从而实现单页面应用的页面跳转功能。

AngularJS 路由允许我们通过不同的 URL 访问不同的内容。

通过 AngularJS 可以实现多视图的单页Web应用(single page web application,SPA)。

通常我们的URL形式为 http://cnblogs.com/first/page,但在单页Web应用中 AngularJS 通过 # + 标记 实现,例如:

http://cnblogs.com/#/first
http://cnblogs.com/#/second
http://cnblogs.com/#/third

当我们点击以上的任意一个链接时,向服务端请的地址都是一样的 (http:/cnblogs.com/)。 因为 # 号之后的内容在向服务端请求时会被浏览器忽略掉。 所以我们就需要在客户端实现 # 号后面内容的功能实现。 AngularJS 路由 就通过 # + 标记 帮助我们区分不同的逻辑页面并将不同的页面绑定到对应的控制器上。

 

01

 

路由使用

① 引入文件并注入依赖

<script src="angular-route.min.js"></script>
var app = angular.module("myApp",['ngRoute']);

② 创建一个布局模板

之所以要创建布局模板,是为了告诉AngularJS应该将布局渲染到何处。通过ng-view指令,我们可以精确的指定模板视图在DOM中的渲染位置。

<div ng-app="myApp">
<a ng-href="#/bq1">标签1</a>
<a ng-href="#/bq2">标签2</a>
<a ng-href="#/bq3">标签3</a>
<a ng-href="#/bq4">标签4</a>
<div ng-view></div>
</div>

③ 创建一些模板视图

myBq1.html

<p>这是标签1</p>

myBq2.html

<p>这是标签2</p>

myBq3.html

<p>这是标签3</p>

myBq4.html

<p>这是标签4</p>

④ 定义路由表

app.config(['$routeProvider',function($routeProvide) {
$routeProvide
.when('/',{templateUrl:"home.html"})
.when('/music',{templateUrl:"myMusic.html"})
.when('/movie',{templateUrl:"myMovie.html"})
.when('/novel',{templateUrl:"myNovel.html"})
.otherwise({redirectTo:'/'});
}]);

02

 

深入路由

① 涉及到的服务与指令

  • $routeProvider 用来定义路由表,我们会用到里面的when和otherwise两个方法。
  • $routeParams 用来保存地址栏中的参数,也提供了通配某类地址的能力。
  • $location 用来分析处理url。
  • $ng-view 用来指定加载模板视图的区域。

② $location.path()详解

如果没有参数,返回当前路径,即#号后的内容;也可以传入字符串,将当前路径修改为字符串的内容,并触发路由变化。 
假设当前url:http://localhost:63342/RouteDemo/index.html#/

//返回'/'
$location.path();
//将当前url修改为:http://localhost:63342/RouteDemo/index.html#/music
$locaiton.path('/music');
//返回'/music'
$locaiton.path();

③ when及otherwise详解

when方法能够接收两个参数,第一个参数是路由路径,这个路径会与$location.path()的值进行匹配,如果没有任何一个when方法匹配到,那么将会执行otherwise方法。第二个参数是配置对象,它的六个属性分别是controller,template,templateUrl,resolve,redirectTo,reloadOnSearch。

  • controller 
    该属性值可以是一个字符串,也可以是一个函数。如果是字符型,则会搜索相应的控制器,如果是函数,那么该函数代表控制器(可以用controllerAs为控制器命名或起别名)。控制器会与路由所创建的作用域关联在一起,并且转到该路径时都会执行一次控制器中的内容。
//每次路径变为/music触发路由变化时都会执行一次控制器中的内容
app.config(['$routeProvider',function($routeProvide) {
$routeProvide.when('/music'{templateUrl:"myMusic.html",controller:"myController"})
}]);
app.controller('myController',function($scope) {
console.log("123");
});
  • controllerAs 
    给controller属性值代表的控制器起个别名,以便之后引用。
  • template 
    值是一个字符串,代表一个Html模板,AngularJS会拿该模板来渲染。
  • templateUrl 
    值是一个字符串,代表一个存着Html模板的路径,AngularJS会拿该路径下的Html模板来渲染。
  • resolve 
    值是一个对象,该对象属性名是可以注入到控制器的依赖,属性值可包含下列内容。

只有当resolve对象里所有promise对象执行完毕后才会注入到控制器,此时才会发生路由变化,因此可以解决页面闪烁问题(加载页面后才获取到数据去更新视图)。我们来看看对比,下面这个例子控制器注入的a是自定义的myService服务,注入的b则是从服务器端获取到的数据。 
test.html代码如下。

<p>我是测试界面 {{ name }}</p>
<div ng-repeat="name in list">{{ name }}</div>

index.html代码如下。

<body ng-app="myApp">
<div ng-app="myApp">
<a ng-href="#/test">测试</a>
<div ng-view></div>
</div>
<script>
var app = angular.module("myApp",['ngRoute']);
app.value("myService","张三");
app.config(['$routeProvider',function($routeProvide) {
$routeProvide
.when('/test',{templateUrl:"test.html",
controller:function($scope,a,b) {
$scope.name = "你好"+a;
$scope.list = b.data;
},
resolve:{
a:"myService",
b:function($http,$timeout) {
var promise = $timeout(function() {
return $http.get("http://localhost:3000/person");
},3000);
return promise;
}
}});
}]);
</script>
</body>

如果直接在控制器而不是resolve中请求,则index.html代码如下。

<body ng-app="myApp">
<div ng-app="myApp">
<a ng-href="#/test">测试</a>
<div ng-view></div>
</div>
<script>
var app = angular.module("myApp",['ngRoute']);
app.value("myService","张三");
app.config(['$routeProvider',function($routeProvide) {
$routeProvide
.when('/test',{templateUrl:"test.html",
controller:function($scope,$http,$timeout,a) {
$scope.name = "你好"+a;
var promise = $timeout(function() {
return $http.get("http://localhost:3000/person");
},3000);
promise.then(function(response) {
$scope.list = response.data;
});
},
resolve:{
a:"myService"
}});
}]);
</script>
</body>

两者效果如下,可以看到写在控制器中的代码不仅需要自己处理逻辑(控制器不推荐写太复杂的逻辑)从promise的success function中取得repsonse参数,而且页面加载不一致,服务器获取的数据在获得后才加载,而在resolve中写,只有等promise执行完毕后才会跳转,然后同步加载整个页面。

- redirectTo 
值是一个字符串或一个函数,该属性写在otherwise中,代表着在when中找不到相应路径时的重定向。如果是字符串,路径会被替换成该值,如果是函数,它有三个参数,第一个是当前路径的路由参数,第二个是当前路径,第三个当前Url的查询串,路径会被替换成该函数的返回值,替换后都会触发路由变化。 
- reloadOnSearch 
值是一个布尔值,为true的时候$location.search()发生变化时就会重新加载路由,location.search是从当前URL的?号开始(包括?号)的字符串。

④ $routeParams

我们可以在路由参数的前面加上:号,AngularJS会把它解析出来并传递给$routeParams。 
  下面的例子中我们将123456传给value,AngularJS把其解析出来,在$routeParams中添加一个名为value的键,值为123456,我们可以将该服务注入到控制器中使用。 
  test.html代码如下。

<p>我是测试界面 {{ display }}</p>
<body ng-app="myApp">
<div ng-app="myApp">
<a ng-href="#/test/123456">测试</a>
<div ng-view></div>
</div>
<script>
var app = angular.module("myApp",['ngRoute']);
app.config(['$routeProvider',function($routeProvide) {
$routeProvide
.when('/test/:value',{templateUrl:"test.html",
controller:function($scope,$routeParams) {
$scope.display = $routeParams.value;
}});
}]);
</script>
</body>

⑤ 路由事件

$route服务在路由过程中的每个阶段都会触发不同的事件,可以为这些事件设置监听器并做出响应。路由事件都是系统自动从$rootScope广播下去的,我们最好的做法是在$rootScope中监听,而最佳设置的地方就是run方法,可以保证不会漏掉任何路由变化。 
  下面是四种不同的路由事件。

  • $routeChangeStart 
    AngularJS在路由改变之前就会广播此事件,在广播后,路由会开始加载路由变化所需要的所有依赖,并且模板和resolve键中的promise都会被resolve。
  • $routeChangeSuccess 
    在路由的依赖加载,且resolve键中所有promise都resolve了就会广播此事件。
  • $routeChangeError 
    在resolve键中任何一个promise被拒绝或者失败后会广播此事件,也就是说,此事件与$routeChangeSuccess互斥。
  • $routeUpdate 
    在reloadOnSearch属性设置为false的情况下,重新使用某个控制器的实例会广播该事件。

AngularJS 路由精分的更多相关文章

  1. AngularJS 路由

    AngularJS 路由允许我们通过不同的 URL 访问不同的内容. 通过 AngularJS 可以实现多视图的单页Web应用(single page web application,SPA). 通常 ...

  2. Angularjs路由需要了解的那点事

    Angularjs路由需要了解的那点事 我们知道angularjs是特别适合单页面应用,为了通过单页面完成复杂的业务功能,势必需要能够从一个视图跳转到另外一个视图,也就是需要在单个页面里边加载不同的模 ...

  3. 【转】AngularJS路由和模板

    1. AngularJS路由介绍 AngularJS路由功能是一个纯前端的解决方案,与我们熟悉的后台路由不太一样.后台路由,通过不同的URL会路由到不同的控制器上(controller),再渲染(re ...

  4. AngularJS路由和模板

    前言 如果想开发一款类似gmail的web应用,我们怎么做呢? 以jQuery的思路,做响应式的架构设计时,我们要监听所有点击事件,通过事件函数触发我们加载数据,提交,弹框,验证等的功能:以 Angu ...

  5. AngularJS路由跳转

    AngularJS是一个javascript框架,通过AngularJS这个类库可以实现目前比较流行的单页面应用,AngularJS还具有双向数据绑定的特点,更加适应页面动态内容. 所谓单页面应用就是 ...

  6. AngularJS进阶(二)AngularJS路由问题解决

    AngularJS路由问题解决 遇到了一个棘手的问题:点击优惠详情时总是跳转到药店详情页面中去.再加一层地址解决了,但是后来发现问题还是来了: Could not resolve 'yhDtlMain ...

  7. AngularJS路由使用案例

    AngularJS路由使用案例: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...

  8. angularjs路由path方式实现原理探究

    angularjs路由 https://angular.io/guide/router 通过URL解释, 来定位客户端生成的浏览器端视图. 你可绑定路由到页面的链接上, 当用户点击链接, 可以浏览到相 ...

  9. AngularJS路由系列(6)-- UI-Router的嵌套State

    本系列探寻AngularJS的路由机制,在WebStorm下开发.本篇主要涉及UI-Route的嵌套State. 假设一个主视图上有两个部分视图,部分视图1和部分视图2,主视图对应着一个state,两 ...

随机推荐

  1. linux Module驱动开发-一切刚刚开始

    linux内核是可以高度定制的,通过配置编译选项达到定制的目的. 在配置kernel编译选项时驱动程序的编译选项一般有三种,不编译.编译为内核驱动.编译为模块驱动.所以linux驱动一般分为两类,内核 ...

  2. 多线程编程学习一(Java多线程的基础).

    一.进程和线程的概念 进程:一次程序的执行称为一个进程,每个 进程有独立的代码和数据空间,进程间切换的开销比较大,一个进程包含1—n个线程.进程是资源分享的最小单位. 线程:同一类线程共享代码和数据空 ...

  3. Linux平台 Oracle 12cR2 RAC安装Part3:DB安装

    Linux平台 Oracle 12cR2 RAC安装Part3:DB安装 四.DB(Database)安装 4.1 解压DB的安装包 4.2 DB软件安装 4.3 ASMCA创建磁盘组 4.4 DBC ...

  4. jsp fmt标签详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt326 JSTL标签提供了对国际化(I18N)的支持,它可以根据发出请求的客户 ...

  5. Color.js增强你对颜色的控制

    往逝之因 不要低头,皇冠会掉...  可你又没有皇冠 Color.js 增强你对颜色的控制 阅读目录 轻松管理颜色--color.js库 使用color.js Accessor Methods 你该知 ...

  6. Assert中的静态方法

    junit中的assert方法全部放在Assert类中,总结一下junit类中assert方法的分类. 1.assertTrue/False([String message,]boolean cond ...

  7. 第四次作业 四则运算器在C++层面上的进一步思考

    OOA(Object Oriented Analysis,面向对象分析) 从客观存在的事务和事务之间的关系,归纳出有关对象(包括对象的属性和行为)以及对象之间的联系,并将具有相同属性和行为的对象用一个 ...

  8. 201521123105 第三周Java学习总结

    1. 本周学习总结 对象(实际个体) 对象与类 类(模板) 2.书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private ...

  9. 201521123111《Java程序设计》第12周学习总结

    本次作业参考文件 正则表达式参考资料 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String ...

  10. 201521123069 《Java程序设计》 第9周学习总结

    1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. (1)使用try...catch语句捕获异常(try块后可跟一个或多个catch块,注意子类异常要放在父类异常前面, ...