通过路由管理视图间切换 - AngularJS路由解析
模板的视图刷新
ng-view这个指令和路由组合之后就可以将$route对应的视图放入指定的HTML中,这一过程中它会创建自己的作用域并将模板嵌套在内部.
ng-view指令的优先级是1000(终极),所以AngularJS不会运行同一元素上的低优先级指令,也就是说如果一个div有ng-view指令,它上面再写其他指令都是没意义的.
ng-view这个指令每次会创建一个新的作用域,同时移除上一个视图及其作用域,并将新的作用域和模板关联起来.如果路由中又相关的定义,那么继续将对应的控制器和当前创建的作用域联系起来,这些都完成后会触发$viewContentLoaded事件.
视图的刷新是在每次的$routeChangeSuccess事件之后.
路由的定义
路由通常在模块config部分,通过$routeProvider的when和otherwise定义.
|
1
2
3
4
5
6
7
8
9
|
angular.module('myApp',[]).config(['$routeProvider',function($routeProvider){ $routeProvider.when('/',{ templateUrl: 'view/index.html', controller:: 'IndexController' }) .ohterwise({ redirectTo: '/' });}]); |
上面的代码很容易理解,即使不会看意思猜都能猜出来,这里介绍一些其他的.when()的第二个参数是一个配置对象,通常我们只需要配置一下templateUrl和controller就行了,有些时候我们需要更多.
(1) controller
它的作用是将指定的控制器与路由所创建的新作用域关联在一起,如果参数是字符串,那么就从所有注册过的控制器中寻找对应的内容进行关联,如果参数是函数,那么就会直接关联这个函数.
(2) template 和 templateUrl
这两个其实都是HTML模板,区别只是一个是String形式写在route中,另一个则会通过XHR读取指定文件(或者从$templateCache).这里面的内容都会被渲染到具有ng-view指令的DOM中.
(3) resolve
这个感觉可能不是太常用,不过非常有用.它通常是一个对象,key-value的形式.key是注入到控制器中的依赖名称.如果你还不明白它做了什么,比较通俗易懂的说法就是讲一个服务或者一个值在控制器加载以及$routeChangeSuccess触发之前,被设置并注入到控制器.比如这样:
|
1
2
3
4
5
6
7
8
9
|
resolve: { 'flag': ['$someService', function($someService) { if($someService.getFlag()){ return true; }else{ return false; } }];} |
上面代码可以看到,在flag是通过一个服务判断后设置的,它会被注入到控制器,所以你在控制器可以使用它了.补充一点就是,这里"key-value"格式中,value可以是服务的名字或者返回值,函数或者可以被resolve的promise对象,它会被注入到控制器.
(4) redirectTo
这个看名字就知道干嘛的了...不解释
(5) reloadOnSearch
这个参数基本上大家都没用过,因为通常都使用默认值(true).默认在$location.search()变化时会重新加载路由,如果这个参数为false,那么当URL查询条件变化时就不会重新加载路由.这个功能当你使用本地分页时对URL是更友好的.
路由参数
路由里可以有参数,只要将when()的第一次参数写成类似'/users/:user_id'这样就行了,AngularJS会把它解析出来并传递给$routeParams.
你在从他人哦哦了人中就可以通过$routeParams.user_id的方式获取这个值.
对URL的控制 - $location
一般情况下我们对地址栏中的URL的操作要通过window.location对象,AngularJS提供了一个服务用以解析地址栏中的URL,也就是$location.通过它你可以访问应用当前路径所对应的路由,以及修改路径和处理导航.
应用需要在内部进行跳转时是使用$location进行的,注意的是它并没有刷新整个页面的能力.如果要刷新整个页面可以使用$window.location对象.
下面简单介绍一下常用的API,推荐还是去看官网文档.
(1) path()
获取以及修改当前路径,可以和HTML5的历史API直接进行交互,所以前进后退按钮可以生效.
(2) replace()
如果希望跳转后不能后退回去,可以这么写:$location.path('/').replace()
(3) search()
获取或者修改URL中的查询串(也就是查询参数),设置可以是对象或者字符串均可.
(4) url()
和path()类似,只不过操作的是URL而不是路径.
两种路由模式
如果你看过官网的路由Demo,应该会发现在URL中包含#符号.之所以有这个东西是因为AngularJS一些默认情况下的Demo都是基于路由的标签模式.不同路由模式在浏览器地址栏中会使用不同的URL格式.$location默认是标签模式.
(1) 标签模式
标签模式就利用内部链接的技巧,URL路径以#符号开头.AngularJS本身不会重写<a>标签,也不需要进行任何配置或者服务器支持.它的URL看起来类似这样:http://angular.app.com/#/users
默认的AngularJS配置就是这样的,不要任何设置.通常标签模式是HTML5模式的一种降级方案.
(2) HTML5模式
HTML5模式就接近于我们正常的URL,同一个地址它看起来是这样的:http://angular.app.com/users. 在AngularJS内部,$location服务通过HTML5历史API让应用能够使用普通的URL路径来访问路由,当浏览器不支持HTML5历史API时,$location服务会自动使用标签模式的URL作为替代 方案.在HTML5模式中,AngularJS会负责重写<a href=""></a>中的链接.也就是说AngularJS会根据浏览器的能力在编译时决定是否要重写href=""中的链接.
后端服务器也需要支持URL重写,服务器需要确保所有请求都返回index.html,以支持HTML5模式.这样才能确保由AngularJS应用来处理路由.
当在HTML5模式的AngularJS中写链接时,永远都不要使用相对路径.如果你的应用是在根路径中加载的,这不会有什么问题,但如果是在其他路径中,AngularJS应用就无法正确处理路由了.
路由的事件
事件这个词在前端出现的频率真是高,根本拦不住,哪哪都是.$route服务在路由过程中的每个阶段都会触发不同的事件,可以为这些不同的路由事件设置监听器并做出响应.
一共有4个事件用来监听路由的状态变化: $routeStartChange, $routeChangeSuccess, $routeChangeError, $routeUpdate.
其中最常用的是前两个,这里稍微解释一下.
(1) $routeStartChange
看名字就能猜出来它表示的是路由开始变化的事件,在浏览器地址栏发生变化之前AngularJS会先广播一下这个事件.路由会开始加载所有需要的依赖,模板和resolve部分的内容也会注入.
|
1
2
3
4
5
6
|
angular.module('myApp', []) .run(['$rootScope', '$location', function($rootScope, $location){ $rootScope.$on('$routeChangeStart', function(evt, next, current){ console.log('route begin change'); }); }]); |
解释一下事件的参数,evt是事件对象,可以从中读取到一些route的信息.next是将要导航到的路由,current是当前的URL.
可以看见在这个时期我们可以做很多有用的事,因为此时仅仅是路由开始变化,对应的内容都还没来得及发生改变.这里我们可进行permission的校验,loading画面的加载,对应路由信息的读取等等.
(2) $routeChangeSuccess
在路由的所有依赖都被注入加载后,AngularJS会对外广播路由跳转成功的事件.
|
1
2
3
4
5
6
|
angular.module('myApp', []) .run(['$rootScope', '$location', function($rootScope, $location) { $rootScope.$on('$routeChangeSuccess', function(evt, current, previous) { console.log('route have already changed'); }); }]) |
这里也稍微解释下三个参数,evt是AngularJS事件对象,current是当前所处路由,previous是上一个路由.
剩下两个不太常用的事件,大家去看官方API说明吧,这里不介绍了.
应用场景以及可扩展性
对于SPA应用尤其是AngularJS这种胖客户端的应用,路由的部分一直可以大做文章的.我们可以把一些页面的基本信息配置到路由中.上面说过了when()的第二个参数是一个对象,出了AngularJS为我们定义好的一些属性之外,我们完全可以自己进行扩展,这些扩展出来的信息,又可以通过注入的方式,加载到每一个路由对应的控制器中.
通过这样方式我们就可以解耦出来一些每个页面都有,但是能抽象成公共信息的这么一类东西.比如之前我一篇博客中提到的通过路由控制页面访问权限,又或者每个页面都有一个说明当前页面主题的title导航之类的东西,这种信息也可以淡出抽到route中.又或者在视图切换的间隙中,加入loading动画都可以在路由中实现.
复杂的SPA通过路由进行视图和视图之间的管理和联系,路由的规范往往是牵一发而动全身的.通常文件的视图结构就映射了路由的URL结构,这些结构又在一定程度上符合restful定位资源的含义,好的路由让你可以更快速的寻找到对应的文件.
通过路由管理视图间切换 - AngularJS路由解析的更多相关文章
- AngularJS路由和模板
前言 如果想开发一款类似gmail的web应用,我们怎么做呢? 以jQuery的思路,做响应式的架构设计时,我们要监听所有点击事件,通过事件函数触发我们加载数据,提交,弹框,验证等的功能:以 Angu ...
- AngularJS路由系列(6)-- UI-Router的嵌套State
本系列探寻AngularJS的路由机制,在WebStorm下开发.本篇主要涉及UI-Route的嵌套State. 假设一个主视图上有两个部分视图,部分视图1和部分视图2,主视图对应着一个state,两 ...
- AngularJS路由系列(3)-- UI-Router初体验
本系列探寻AngularJS的路由机制,在WebStorm下开发. AngularJS路由系列包括: 1.AngularJS路由系列(1)--基本路由配置2.AngularJS路由系列(2)--刷新. ...
- AngularJS路由系列(2)--刷新、查看路由,路由事件和URL格式,获取路由参数,路由的Resolve
本系列探寻AngularJS的路由机制,在WebStorm下开发.主要包括: ● 刷新路由● 查看当前路由以及所有路由● 路由触发事件● 获取路由参数 ● 路由的resolve属性● 路由URL格式 ...
- AngularJS路由系列(1)--基本路由配置
本系列探寻AngularJS的路由机制,在WebStorm下开发.主要包括: ● 路由的Big Picture ● $routeProvider配置路由 ● 使用template属性 ● 使用temp ...
- AngularJS 路由和模板实例及路由地址简化方法
最近一同事在学习AngularJS,在路由与模板的学习过程中遇到了一些问题,于是今天给她写了个例子,顺便分享出来给那些正在学习AngularJS的小伙伴们. 话说这AngularJs 开发项目非常的爽 ...
- AngularJS路由系列(5)-- UI-Router的路由约束、Resolve属性、路由附加数据、路由进入退出事件
本系列探寻AngularJS的路由机制,在WebStorm下开发.主要包括: ● UI-Router约束路由参数● UI-Router的Resolve属性● UI-Router给路由附加数据● UI- ...
- AngularJS路由系列(4)-- UI-Router的$state服务、路由事件、获取路由参数
本系列探寻AngularJS的路由机制,在WebStorm下开发.主要包括: ● UI-Router的$state服务● UI-Router的路由事件● UI-Router获取路由参数 Angular ...
- flutter最简单轻量便捷的路由管理方案NavRouter
大家好,我是CrazyQ1,今天给大家推荐一个路由管理方案,用的非常不错的,叫nav_router. 项目地址是:https://github.com/fluttercandies/nav_route ...
随机推荐
- 算法复习——矩阵树定理(spoj104)
题目: In some countries building highways takes a lot of time... Maybe that's because there are many p ...
- 学习 JSP:第二步 创建一个JSP Web Project
接上文 学习 JSP:第一步Eclipse+Tomcat+jre(配置环境) [创建新工程](Dynamic Web Project) 1.选择 "File-->New-->Dy ...
- 【CCF】高速公路 tarjan强连通缩点
[题意] 给定一个有向图,问图中互相可达(强连通)的点有多少对 [AC] 强连通缩点,缩点后是一个DAG,所以互相可达的点只在强连通块里. #include<iostream> #incl ...
- offsetWidth clientWidth scrollWidth 三者之间的区别和联系
scrollWidth:对象的实际内容的宽度,不包边线宽度,会随对象中内容超过可视区后而变大. clientWidth:对象内容的可视区的宽度,不包滚动条等边线,会随对象显示大小的变化而改变. off ...
- 优化join语句
Mysql4.1开始支持SQL的子查询.这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中.使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的 ...
- P1473 校门外的树3
时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……如今学校决定在某个时刻在某一段种上一 ...
- 标准C程序设计七---72
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- LeetCode OJ-- Spiral Matrix
https://oj.leetcode.com/problems/spiral-matrix/ 螺旋矩阵,逆着转,输出矩阵中的元素. 在纸上模仿,然后记左上角(l1,l2)右上角(l1,r2),左下角 ...
- Maven教程:tutorialspoint-maven
来自turorialspoint的Maven教程(英文),官网:http://www.tutorialspoint.com/maven/index.htm 这个教程在国内已经被翻译成中文,官网:htt ...
- js获得checkbox选中值及input后面的文本
原文:http://blog.csdn.net/u014079773/article/details/51865596 js如何获得多个checkbox选中的值及input后面所跟的文本 <!d ...