在你的应用程序中 ,大多数状态都会有一个相关联的url。URL的路由不是事后才定义好的,而是之前就定义好的。
$stateProvider .state('contacts', { url: "/contacts", templateUrl: 'contacts.html' })
现在当用户访问到index.html/contacts时,
'contacts' 状态将会被激活并且主ui-view
将会被 'contacts.html'填充。另外,如果用户是通过transitionTo('contacts')转变到'contacts'状态,那么url将会被更新至
index.html/contacts。
URL Parameters
Basic Parameters
通常,URL都会包含一个动态部分即参数。有几种方式指定参数,基本的方法如下:
$stateProvider
.state('contacts.detail', {
url: "/contacts/:contactId",
templateUrl: 'contacts.detail.html',
controller: function ($stateParams) {
// If we got here from a url of /contacts/42
expect($stateParams).toBe({contactId: 42});
}
})
另外,你还可以用大括号:
// identical to previous example
url: "/contacts/{contactId}"
Examples:
'/hello/'
- 只有当路径是 '/hello/'时才匹配。 There is no special treatment for trailing slashes, and patterns have to match the entire path, not just a prefix.'/user/:id'
- 匹配'/user/bob' 或者 '/user/1234!!!' 甚至 '/user/' ,但是不是 '/user' or '/user/bob/details'.。第二段路径参数将被识别为参数 'id'.'/user/{id}'
- 与上面的例子相同,但是用了大括号
Regex Parameters
用大括号来给参数指定正则表达式:
// will only match a contactId of one to eight number characters
url: "/contacts/{contactId:[0-9]{1,8}}"
Examples:
'/user/{id:[^/]*}'
- 与上面的'/user/{id}'相同
'/user/{id:[0-9a-fA-F]{1,8}}'
- 类似于前面的例子,但只有当id参数包含1到8个十六进制数字相匹配。'/files/{path:.*}'
-匹配以'/files/'的任何URL, and captures the rest of the path into the parameter 'path'.'/files/*path'
- 同上。特殊语法捕捉所有。
Warning: Don't put capturing parentheses into your regex patterns, the UrlMatcher in ui-router adds those itself around the entire regex. You're effectively introducing a second capture group for the same parameter, which trips up the numbering in the child URL. You can use non-capturing groups though, i.e. (?:...) is fine.
Query Parameters
你可以在'?'之后定义你的查询参数:
url: "/contacts?myParam"
// will match to url of "/contacts?myParam=value"
url: "/contacts?myParam1&myParam2"
// will match to url of "/contacts?myParam1=value1&myParam2=wowcool"
URL Routing for Nested States
Appended Routes (default)
当url路由和嵌套状态同时使用时,默认在子状态的url中追加父状态的url:
$stateProvider
.state('contacts', {
url: '/contacts',
...
})
.state('contacts.list', {
url: '/list',
...
});
So the routes would become:
- 'contacts' state matches
"/contacts"
- 'contacts.list' state matches
"/contacts/list"
. The urls were combined.
Absolute Routes (^)
如果你想使用绝对的url进行匹配,需要在你的url前面添加 '^':
$stateProvider
.state('contacts', {
url: '/contacts',
...
})
.state('contacts.list', {
url: '^/list',
...
});
So the routes would become:
- 'contacts' state matches
"/contacts"
- 'contacts.list' state matches
"/list"
. The urls were not combined because^
was used.
$stateParams Service
正如你之前所见,$stateParams服务是一个对象,其中key-value包含了url的参数。 $stateParams是一个将参数提供给控制器或者其他服务的一个很好的方式。
Note: $stateParams service must be specified as a state controller, and it will be scoped so only the relevant parameters defined in that state are available on the service object.
// If you had a url on your state of:
url: '/users/:id/details/{type}/{repeat:[0-9]+}?from&to'
// Then you navigated your browser to:
'/users/123/details//0'
// Your $stateParams object would be
{ id:'123', type:'', repeat:'0' }
// Then you navigated your browser to:
'/users/123/details/default/0?from=there&to=here'
// Your $stateParams object would be
{ id:'123', type:'default', repeat:'0', from:'there', to:'here' }
Two Important $stateParams
Gotchas
$stateParams
对象只有在状态被激活并且所有的依赖注入之后才会被传播。这意味着你不能在resolve
函数中范文。但是可以使用$state.current.params
来访问$stateProvider.state('contacts.detail', { resolve: { someResolve: function($state){ //*** We cannot use $stateParams here, the service is not ready ***// //*** Use $state.current.params instead ***// return $state.current.params.contactId + "!" }; }, // ... })
- 在状态控制器中,
$stateParams
对象仅包含在当前状态下注册的参数。所有你不会看到在其他状态下注册的参数,包括父状态。$stateProvider.state('contacts.detail', { url: '/contacts/:contactId', controller: function($stateParams){ $stateParams.contactId //*** Exists! ***// } }).state('contacts.detail.subitem', { url: '/item/:itemId', controller: function($stateParams){ $stateParams.contactId //*** Watch Out! DOESN'T EXIST!! ***// $stateParams.itemId //*** Exists! ***// } })
$urlRouterProvider
$urlRouterProvider 负责观察 $location。当$location 发生变化时,他将允许一系列匹配的规则。 $urlRouterProvider is used behind the scenes anytime you specify a url
in a state configuration. All urls are compiled into a UrlMatcher object (see $urlMatcherFactory below).
$urlRouterProvider 有几个方法可以在模块配置中直接使用。
when()
for redirection
Parameters:
what
String | RegExp | UrlMatcher The incoming path that you want to redirect.handler
String | Function The path you want to redirect your user to.
handler
as String
如果handler 是一个字符串,它会被作为重定向处理,并且根据语法匹配 (i.e. like String.replace() for RegExp, or like a UrlMatcher pattern otherwise).
app.config(function($urlRouterProvider){
// when there is an empty route, redirect to /index
$urlRouterProvider.when('', '/index');
// You can also use regex for the match parameter
$urlRouterProvider.when('/aspx/i', '/index');
})
handler
as Function
If the handler is a function, it is injectable. It gets invoked if $location matches. You have the option of inject the match object as $match
The handler can return:
- falsy to indicate that the rule didn't match after all, then $urlRouter will continue trying to find another one that matches.
- a String, which is treated as a redirect and passed to $location.url()
- nothing or any truthy value tells $urlRouter that the url was handled
Here's the actual code that we use to register state's that have urls behind the scenes.
$urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {
if ($state.$current.navigable != state || !equalForKeys($match, $stateParams)) {
$state.transitionTo(state, $match, false);
}
}]);
otherwise()
for invalid routes
Parameters:
path
String | Function The url path you want to redirect to or a functionrule
that returns the url path. The function version is passed two params:$injector
and$location
.
app.config(function($urlRouterProvider){
// if the path doesn't match any of the urls you configured
// otherwise will take care of routing the user to the specified url
$urlRouterProvider.otherwise('/index');
// Example of using function rule as param
$urlRouterProvider.otherwise(function($injector, $location){
... some advanced code...
});
})
rule()
for custom url handling
Parameters:
handler
Function A function that takes in the $injector and $location services as arguments. You are responsible for returning a valid path as a string.
app.config(function($urlRouterProvider){
// Here's an example of how you might allow case insensitive urls
$urlRouterProvider.rule(function ($injector, $location) {
var path = $location.path(), normalized = path.toLowerCase();
if (path != normalized) return normalized;
});
})
$urlMatcherFactory and UrlMatchers
Defines the syntax for url patterns and parameter placeholders. This factory service is used behind the scenes by $urlRouterProvider to cache compiled UrlMatcher objects, instead of having to re-parse url patterns on every location change. Most users will not need to use $urlMatcherFactory directly, however it could be useful to craft a UrlMatcher object and pass it as the url to the state config.
Please refer to the comment documentation within the $urlMatcherFactory file to learn more.
var urlMatcher = $urlMatcherFactory.compile("/home/:id?param1");
$stateProvider.state('myState', {
url: urlMatcher
});