angular的uiRouter服务学习(4)
本篇接着上一篇angular的uiRouter服务学习(3)继续讲解uiRouter的用法
本篇主要讲解uiRouter的url路由
大多数情况下,状态是和url相关联的: 当url改变,激活对应的状态.当状态发生改变,同步url. 所以,在设置状态的一开始,就应该把url路由的设计考虑进去,同时保持路由和状态的分离.
其实在之前几篇的栗子里,已经多次用到了url路由,比如:
$stateProvider
.state('contacts', {
url: "/contacts",
templateUrl: 'contacts.html'
})
当url被导航到baseUrl/contacts,contacts状态就会被激活,然后ui-view元素就会被contacts.html填充.另外,如果我们使用transitionTo('contacts')来激活contacts状态,url也会被更新为 baseUrl/contacts
URL 参数
基本参数
通常,url会有动态的部分,这些部分就是url参数.有几种方法可以定义url参数.下面是一个最基本的栗子:
$stateProvider.state('contacts.detail', {
url: "/contacts/:contactId",
templateUrl: 'contacts.detail.html',
controller: function ($stateParams) {
$scope.contactId = $stateParams.contactId;
}
})
也可以使用花括号:
url: "/contacts/{contactId}"
下面举几个常用的栗子:
<p>
hello/路由:<a href="hello/">'hello/'</a>
</p> <p>
hello/1路由: 匹配'/hello/'无效 <a href="hello/1">'hello/1 无效'</a>
</p> <p>
hello路由: 匹配'/hello/'无效 <a href="hello">'hello 无效'</a>
</p> <p>
user/1路由: 匹配'user/{id}'或'user/:id' <a href="user/1">'user/:id'</a>
</p> <p>
user/1/路由: 匹配'user/:id'无效 <a href="user/1/">'user/:id/ 无效'</a>
</p> <p>
user/路由: <a href="user/">'user/'</a>
</p> <p>
user/anotheruser路由: 匹配'user/{id:int}'无效 <a href="user/anotheruser">'user/{id:int} 下无效'</a>
</p>
var hello = {
name:'hello',
/*注意,只能匹配到'/hello/',最后一个/不能少,最后一个/后面也不能再有其他内容*/
url:'/hello/',
template:'<h3>/hello/</h3>'
};
var user = {
name:'user',
/*注意,可以匹配到/user/,也就是说,参数为空也能被匹配到,使用花括号和使用:完全一致*/
/*url:'/user/:id',*/
/*url:'/user/{id}',*/
/*使用了:int,user/后面必须是一个整数,否则不匹配*/
url:'/user/{id:int}',
templateProvider: function($stateParams){
return '<h1>user/'+$stateParams.id+'</h1>'
}
};
'/hello/': 只能匹配到'/hello/',最后一个/不能少,最后一个/后面也不能再有其他内容, 'hello/1'无效, 'hello'也无效
'/user/:id' 或 'user/{id}': 两种写法效果一样. 可以匹配 'user/', 可以匹配'user/...', 不能匹配'user/.../' user后面内容会被作为$stateParams的id属性值
'/user/{id:int}': id必须为整数. 不能匹配到'user/anotheruser'这样id不是整数的url
正则参数
使用花括号来定义参数,可以自定义正则来匹配url:
var user = {
name:'user',
/*id的长度在1-8位之间*/
url:'/user/{id:[0-9a-fA-F]{1,8}}',
templateProvider: function($stateParams){
return '<h1>user/'+$stateParams.id+'</h1>'
}
};
下面举几个正则的栗子:
<p>
contacts/0123456789路由: 匹配'contacts/{contactId:[0-9]{1-8}}'无效
<a href="contacts/0123456789">'contacts/{contactId:[0-9]{1-8}}'</a>
</p>
var user = {
name:'user',
/*相当于{id}*/
/*url:'/user/{id:[^/]*}',*/
/*id的长度在1-8位之间*/
url:'/user/{id:[0-9a-fA-F]{1,8}}',
templateProvider: function($stateParams){
return '<h1>user/'+$stateParams.id+'</h1>'
}
};
var contacts = {
name:'contacts',
/*匹配0-9数字,长度在1-8之间*/
url:'/contacts/{contactId:[0-9]{1,8}}',
templateProvider:function($stateParams){
return '<h1>contacts/'+$stateParams.contactId+$stateParams.myParam+$stateParams.myName+'</h1>'
}
};
'/user/{id:[^/]*}': 相当于'/user/:id' 和 '/user/{id}'
'contacts/{contactId:[0-9]{1-8}}': contactsId是长度为1-8位的数字, 比如上面超过8位的url 'contacts/0123456789' ,就不会被匹配到.
'/user/{id:[0-9a-fA-F]{1,8}}': id是长度为1-8的任意字符.
匹配包含'/'的全部内容作为参数:
前面说到的匹配路径,都是把 / 后面的内容捕获为参数的,但如果 / 后面还有 /,那么不仅不会被捕获,而且url不会被匹配到.如果需要捕获 / 后面的全部内容作为参数,可以这样写:
<p>
files/paths/path路由: files后面整体作为一个参数<a href="files/paths/path">'/files/*path'</a>
</p>
var files = {
name:'files',
/*匹配/files/开头的所有url,后面有多少个'/'都可以,'/'部分也会被作为path这个整体*/
/*url:'/files/{path:.*}',*/
/*同上,获取包括'/'的全部作为参数的一种简写*/
url:'/files/*path',
templateProvider:function($stateParams){
return '<h1>files/'+$stateParams.path+'</h1>'
}
};
url参数的参数:
还可以把url的参数也可以被作为参数捕获到$stateParams里.
<p>
contacts/0123?myParam路由:
<a href="contacts/0123?myParam">'/contacts/{contactId:[0-9]{1-8}}?myParam'</a>
</p>
<p>
contacts/0123?myParam=param&myName=name路由: <a href="contacts/0123?myParam=param&myName=name">'/contacts/{contactId:[0-9]{1-8}}?myParam&myName'</a>
</p>
var contacts = {
name:'contacts',
/*匹配0-9数字,长度在1-8之间*/
/*url:'/contacts/{contactId:[0-9]{1,8}}',*/
/*在上面的基础上,必须要有myParam参数*/
/*url:'/contacts/{contactId:[0-9]{1,8}}?myParam',*/
/*在上面的基础上,必须要有myParam和myName两个参数*/
url:'/contacts/{contactId:[0-9]{1,8}}?myParam&myName',
templateProvider:function($stateParams){
return '<h1>contacts/'+$stateParams.contactId+$stateParams.myParam+$stateParams.myName+'</h1>'
}
};
在url后面加上?myParam,则url的myParam参数值会被捕获,成为$stateParams的myParam属性值.
注意,即使url不带有myParam参数,它一样可以被匹配,$stateParams的myParam属性值就是undefined.
如果要捕获多个参数,可以用 & 符号连接多个参数
嵌套状态的url路由:
追加url(默认方式):
嵌套状态路由匹配时,子状态的url前会加上父状态的url,然后匹配和在一起的那个url:
<p>
contacts/0123?myParam=param&myName=name路由: <a href="contacts/0123?myParam=param&myName=name">'/contacts/{contactId:[0-9]{1-8}}?myParam&myName'</a>
</p> <p>
contacts/list/0123?myParam路由: '/contacts'路由的子路由'/list': <a href="contacts/list/0123?myParam">'/contacts/list'</a>
</p> <p>
list/0123?myParam路由: '/contacts'路由的子路由'^/list'<a href="list/0123?myParam">'/list'</a>
</p>
var contacts = {
name:'contacts',
url:'/contacts',
template:'<div ui-view></div>'
};
var list = {
name:'contacts.list',
url:'/list/{contactId:[0-9]{1,8}}?myParam',
parent:'contacts',
templateProvider:function($stateParams){
return '<h1>contacts/'+$stateParams.contactId+$stateParams.myParam+$stateParams.myName+'</h1>'
}
};
list是contacts的子状态,所以list状态匹配的url应该是父状态的url+子状态的url: '/contacts/list/{contactId:[0-9]{1,8}}?myParam'
绝对url:
在子状态的url前加上 ^ 符号,则子状态的url前不会拼合父状态的url:
同样上面的这个栗子:
url:'^/list/{contactId:[0-9]{1,8}}?myParam'
则子状态匹配的url就是'/list/{contactId:[0-9]{1,8}}?myParam'
$stateParams 服务:
关于$stateParams这个服务,之前的栗子里已经用到过很多次了. 可以知道,它是一个对象,用于存放url里的参数,这里的参数有两种,一种是状态的url属性里定义的参数,另外一个就是url?后面的参数.无论哪一种,每一个参数都会被放在$stateParams对象里.使用$stateParams可以让我们使用url中的任意部分.
注意: $stateParams服务只能用在状态里.不能注入到其它地方.
下面来看一个$stateParams的栗子:
<p>
users/123/detail//0路由: <a href="users/123/details//0">'/users/:id/details/{type}/{repeat:[0-9]+}?from&to'</a>
</p> <p>
users/123/detail/default/0?from=there&to=here路由: <a href="users/123/details/default/0?from=there&to=here">'/users/:id/details/{type}/{repeat:[0-9]+}?from&to'</a>
</p>
var users = {
name:'users',
url:'/users/:id/details/{type}/{repeat:[0-9]+}?from&to',
templateProvider:function($stateParams){
console.log($stateParams);
return '<h1>'+$stateParams.type+' '+$stateParams.repeat+' '+$stateParams.from+' '+$stateParams.to+'</h1>'
}
};
这里url里一共定义了5个参数: id type repeat from to
当导航到匹配的路径时,状态被激活,栗子中的两个url所对应的$stateParams如下:

$stateParams 服务的两个陷阱:
*以下两个问题只存在于老的版本中,最新版本的测试发现,这两个问题都已经没有了.
1.每个状态所对应的$stateParams只包含该状态url里定义的参数,不包含其它状态里定义的参数,即使是父状态,子状态,也不包含.
2.$stateParams和$routeParams一样,是等到状态被激活完成,resolve都解析后才生成的,所以是不能用在resolve函数里的,只能用$state.current.params来替代.
但是新版本的已经解决了这个问题.现在可以在resolve函数里使用了.
$urlRouterProvider
$urlRouterProvider服务用来监测$location. 当$location发生变化时,它会根据你定义的规则一一匹配,直到找到所匹配的. 所有的url都会被编译到一个urlMatcher对象里(详情查看下面的$urlMatcherFactory)
$urlRouterProvider有下面几个方法.可以使用这些方法在模型中进行配置:
app.config(function($urlRouterProvider){
$urlRouterProvider.when().otherwise().rule()
});
.when(what,handler) 方法重定向url:
what: 字符串/正则/urlMatcher对象,表示需要重定向的url
handler: 字符串/函数, 表示要重定向到的url
如果handler是一个字符串,它就是要重定向到的地址.
handler是字符串的栗子:
<p>
空 <a href="/">''</a>
</p>
urlRouting.config(function($urlRouterProvider){
$urlRouterProvider.when('/','/hello/')
});
当点击这个空链接的时候,他会重定向到/hello/,激活对应的状态.
如果handler是函数,那么它可以被注入服务.可以注入$match服务: (这一部分没有搞懂)
.otherwise() 方法重定向url:
传入一个参数,字符串或者函数, 字符串表示你想要重定向到的url地址. 函数返回想要重定向到的地址. 函数可以被注入两个依赖: $injector和$location
urlRouting.config(function($urlRouterProvider){
/*没有匹配到任何状态或者.when()重定向时,重定向到'users/123/details//0'*/
$urlRouterProvider.otherwise('users/123/details//0')
});
打开页面直接重定向到 'users/123/details//0'
.rule() 方法自定义url处理方式:
.rule()方法接受一个函数作为参数,函数可以注入$injector和$location服务.返回一个字符串格式的有效路由.
举个栗子:
<p>
HELLO/ <a href="HELLO/">'HELLO/'</a>
</p>
$urlRouterProvider.rule(function($injector,$location){
var path = $location.path(),normalized = path.toLowerCase();
if(path!==normalized){
return normalized
}
})
通过rule函数,HELLO/会被转换成hello/,激活对应的状态
$urlMatcherFactory和urlMatchers
在前面介绍$urlRouterProvider的.when()方法时,说到.when()的第一个参数what格式可以是字符串,函数,urlMatcher对象.那么什么是urlMatcher对象呢,也就是通过$urlMatcherFactory定义的url规则.
使用$urlMatcherFactory.compile('path')传入一个路由规则.path的定义规则和定义状态时的url定义的规则是一致的:
如果要使用$urlMatcherFactory,需要链入ui.router.util依赖.如果不引入依赖,可以使用ui.router自带的$urlMatcherFactoryProvider
看如下栗子:
urlRouting.config(function($locationProvider,$stateProvider,$urlRouterProvider,$urlMatcherFactoryProvider){ var urlMatcher = $urlMatcherFactoryProvider.compile('/home/:id?param1');
$stateProvider.state('mystate',{
url:urlMatcher,
templateProvider:function($stateParams){
return '<h1>mystate'+ $stateParams.id +'</h1>'
}
});
/*注意如果一个urlMatcher既匹配了状态里的url,又匹配了.when,以状态为准,不会重定向*/
$urlRouterProvider.when(urlMatcher,'hello/');
});
可以看到,.compile里传入了一个路由规则,这个规则可以直接作为状态的url属性值.也可以作为$urlRouterProvider.when()的第一个参数.
参考原文: https://github.com/angular-ui/ui-router/wiki/URL-Routing
angular的uiRouter服务学习(4)的更多相关文章
- angular的uiRouter服务学习(3)
本篇接着上一篇 angular的uiRouter服务学习(2) 继续讲解uiRouter的用法 本篇主要讲解uiRouter的多个命名的视图 我们可以给ui-view元素添加ui-view的值来给它命 ...
- angular的uiRouter服务学习(2)
本篇接着上一篇 angular的uiRouter服务学习(1) 继续讲解uiRouter的用法 本篇主要讲解uiRouter的嵌套状态&嵌套视图 嵌套状态的方法: 状态和状态之间可以互相嵌套, ...
- angular的uiRouter服务学习(1)
angular有内置的路由服务$route:angular -- $route API翻译 使用$route可以帮助实现路由的切换,视图的改变,但是这个内置的$route只包含了基本的功能,在很多场合 ...
- angular的uiRouter服务学习(5) --- $state.includes()方法
$state.includes方法用于判断当前激活状态是否是指定的状态或者是指定状态的子状态. $state.includes(stateOrName,params,options) $state.i ...
- Angular.js之服务与自定义服务学习笔记
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 成为优秀Angular开发者所需要学习的19件事
一款to-do app基本等同于前端开发的"Hello world".虽然涵盖了创建应用程序的CRUD方面,但它通常只涉及那些框架或库也能做到的皮毛而已. Angular看起来似乎 ...
- angular利用ui-router登录检查
angular利用ui-router登录检查 SAP都会有这个问题,session过期或者页面被刷新的情况下应该进入登录页. 监听ui-router的satte事件可以实现当state切换的时候检查登 ...
- angular的splitter案例学习
angular的splitter案例学习,都有注释了,作为自己的备忘. <!DOCTYPE html> <html ng-app="APP"> <he ...
- 介绍Angular的注入服务
其实angular的注入服务是挺复杂的,目前看源码也只看懂了一半,为了不误导大家,我也不讲敢讲太复杂,怕自己都理解错了. 首先我们要知道angular的三种注入方式: 第一种:inference va ...
随机推荐
- C++中public、protected及private使用方法
1.类的一个特征就是封装,public和private作用就是实现这一目的.所以: 用户代码(类外)能够訪问public成员而不能訪问private成员:private成员仅仅能由类成员(类内)和友元 ...
- Linux端口命令
一.开启端口 1.命令行方式 1.开放端口命令: /sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT 2.保存:/etc/rc.d/init.d ...
- [Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction
1.Spring中的数据库支持 把具有相同功能的代码模板抽取到一个工具类中.2.关于jdbc template的应用 jdbcTemplate模板操作类,把访问jdbc的模板抽取到template中, ...
- 【Spring】Spring框架如何集成Hibernate框架
下面个整理一下hibernate和Spring框架的结合. 首先是引入hibernate框架的包.Spring框架的包.数据库驱动包. User.java文件 package cn.shop.bean ...
- 黑客公布2012年最弱智密码Top25(转)
尽管弱密码对安全性的危害大家都知道,但是仍然有很多网民使用超弱密码.日前,黑客公布了一份密码文档,列出了今年最弱智密码. 根据 SplashData 公布的“年度最弱智密码 Top25”,和去年一样, ...
- OpenCV 学习笔记03 findContours函数
opencv-python 4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...
- 8个实用而有趣Bash命令提示行
很多人都对过命令行提示的重要性不屑一顾,甚至是一点都不关心.但是我却一点都不这么认为,一个好的命令行提示可以改变你使用命令的方式.为此,我在internet上找到一些非常实用,优秀,并有趣的bash的 ...
- Inside i++
i++.++i.i=i+1.效率怎么样?看过一本书上说,i++比i=i+1好的地方是因为i=i+1中的那个1要占用一个寄存器,所以速度没有i++快,于是我想验证一下.另外,以前听说过Java中的“i= ...
- tomcat服务器配置字符集为utf-8-彻底解决中文乱码问题
<Connector port="8070" protocol="HTTP/1.1" connectionTimeout="20000" ...
- SharePoint 2013混合模式登陆中 使用 自定义登陆页
接前一篇博客<SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用>,当实现混合模式登陆后,接着我们就 ...