4、Angular-Ui Router URL路由(完结篇)

翻译 2017年07月21日 18:01:09


Most states in your application will probably have a url associated with them. URL Routing was not an afterthought to the state mechanics, but was figured into the design from the beginning (all while keeping states separate from url routing)
应用程序中的大多数状态可能会有一个与之关联的 url。url 路由不是对状态机制的事后考虑, 而是从一开始就被设计到了设计中 (所有的状态都保持与 url 路由分开)

Here's how you set a basic url.
下面是如何设置基本url的方法。

$stateProvider
    .state('contacts', {
        url: "/contacts",
        templateUrl: 'contacts.html'
    })

Now when the user accesses index.html/contacts then the 'contacts' state would become active and the main ui-view will be populated with the 'contacts.html' partial. Alternatively, if the user were to transition to the 'contacts' state via transitionTo('contacts') then the url would be updated to index.html/contacts
当用户访问 index.html/contacts时。然后,“contacts”状态将变为活动,ui-view将被“contacts.html”填充。或者,如果用户通过transitionTo("contacts")切换到“contacts”状态,那么url将被更新为index.html/contacts

URL Parameters
URL参数

Basic Parameters
基本参数

Often, URLs have dynamic parts to them which are called parameters. There are several options for specifying parameters. A basic parameter looks like this:
通常,UR有动态的部分,它们被称为参数。有几个选项可以指定参数。一个基本的参数是这样的:

$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"});
        }
    })

Alternatively you can also use curly brackets:
或者你也可以使用花括号:

// identical to previous example
url: "/contacts/{contactId}" 

Examples:
示例:

  • '/hello/' - Matches only if the path is exactly '/hello/'. There is no special treatment for trailing slashes, and patterns have to match the entire path, not just a prefix.
    '/hello/'-只有在路径完全是“/hello/”的情况下才匹配。对于后面的斜杠没有特殊的处理,并且模式必须匹配整个路径,而不仅仅是一个前缀。
  • '/user/:id' - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or '/user/bob/details'. The second path segment will be captured as the parameter 'id'.
    '/user/:id' - 匹配 '/user/bob' 或 '/user/1234!!!' 或者是 '/user/' 但不是 '/user' 或 '/user/bob/details'. 第二个路径段将被捕获为参数'id'。
  • '/user/{id}' - Same as the previous example, but using curly brace syntax.
    '/user/{id}' - 与前面的示例相同,但使用的是花括号语法。
  • '/user/{id:int}' - The param is interpreted as Integer.
    '/user/{id:int}' - id参数被解释为整数。

Note:
注意

  • Parameter names may contain only word characters (latin letters, digits, and underscore) and must be unique within the pattern (across both path and search parameters).
    参数名称只能包含字母、数字和下划线, 并且在模式中必须是唯一的 (在路径和搜索参数中)。

Using Parameters in Links
在链接中使用参数

To create a link that passes parameters, use the state name like a function and pass it an object with parameter names as keys. The proper href will be generated.
要创建传递参数的链接,可以使用状态名作为函数,并传递带有参数名的对象作为键。将生成适当的href。

For example, using the above state which specified a contactId parameter, create a link like so:
例如, 使用指定了 contactId 参数的上述状态, 创建如下链接:

<a ui-sref="contacts.detail({contactId: id})">View Contact</a>

The value for id can be anything in scope.
id的值可以是任意值。

Regex Parameters
参数正则表达式

A bonus to using curly brackets is the ability to set a Regular Expression rule for the parameter:
使用花括号的一个好处是可以为参数设置正则表达式规则:

// will only match a contactId of one to eight number characters
url: "/contacts/{contactId:[0-9]{1,8}}"

Examples:示例:

  • '/user/{id:[^/]*}' - Same as '/user/{id}' from the previous example.
    '/user/{id:[^/]*}' - 与前一个示例中的“/user/id”相同。
  • '/user/{id:[0-9a-fA-F]{1,8}}' - Similar to the previous example, but only matches if the id parameter consists of 1 to 8 hex digits.
    '/user/{id:[0-9a-fA-F]{1,8}}' - 与前面的示例类似,但是只有当id参数包含1到8十六进制数字时才匹配。
  • '/files/{path:.*}' - Matches any URL starting with '/files/' and captures the rest of the path into the parameter 'path'.
    '/files/{path:.*}' - 匹配任何以'/files/'开头的URL,并将其余路径捕获到参数“path”中。
  • '/files/*path' - Ditto. Special syntax for catch all.

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.
    不要在正则表达式模式中使用捕获括号,ui-router中的UrlMatcher在整个正则表达式中添加了这些括号。您可以有效地为相同的参数引入第二个捕获组,该参数将在子URL中访问编号。也就是说您可以使用非捕获组。
  • Regular expression can't include forward slashes as that's route segment delimiter
    正则表达式不能包含斜杠,因为这是路由分隔符
  • Route parameters with regular expressions can't be optional or greedy
    带有正则表达式的路由参数不能是可选的或贪婪的

Query Parameters
查询参数

You can also specify parameters as query parameters, following a '?':
还可以将参数指定为查询参数, 即'?':

url: "/contacts?myParam"
// will match to url of "/contacts?myParam=value"

If you need to have more than one, separate them with an '&':
如果你需要不止一个查询参数,则把它们用"&"分开。

url: "/contacts?myParam1&myParam2"
// will match to url of "/contacts?myParam1=value1&myParam2=wowcool"

Using Parameters without Specifying Them in State URLs
使用参数而不用在状态URL中指定它们

You still can specify what parameters to receive even though the parameters don't appear in the url. You need to add a new field params in the state and create links as specified in Using Parameters in Links
即使参数没有出现在url中,您仍然可以指定要接收的参数。您需要在状态中添加一个新的字段params,并在指定的链接中使用参数。

For example, you have the state.
例如,你的状态。

.state('contacts', {
        url: "/contacts",
        params: {
            param1: null
        },
        templateUrl: 'contacts.html'
    })

The link you create is
你创建的链接是

<a ui-sref="contacts({param1: value1})">View Contacts</a>

Or you can pass them to $state.go() too.
你也可以在$state.go()方法中使用参数

$state.go('contacts', {param1: value1})

URL Routing for Nested States
嵌套状态的URL路由

Appended Routes (default)
附加路由(默认)

When using url routing together with nested states the default behavior is for child states to append their url to the urls of each of its parent states.
当使用url路由与嵌套状态一起使用时,默认的行为是让子状态将url附加到每个父状态的url。

$stateProvider
  .state('contacts', {
     url: '/contacts',
     ...
  })
  .state('contacts.list', {
     url: '/list',
     ...
  });

So the routes would become:
所以路由会变成:

  • 'contacts' state matches "/contacts"
    'contacts'状态匹配"/contacts"
  • 'contacts.list' state matches "/contacts/list". The urls were combined.
    'contacts.list'状态匹配"/contacts/list"

Absolute Routes (^)
绝对路由(^)

If you want to have absolute url matching, then you need to prefix your url string with a special symbol '^'.
如果你想要有绝对的url匹配,那么你需要在你的url字符串前面加上一个特殊的符号 '^'

$stateProvider
  .state('contacts', {
     url: '/contacts',
     ...
  })
  .state('contacts.list', {
     url: '^/list',
     ...
  });

So the routes would become:
所以路由会变成:

  • 'contacts' state matches "/contacts"
    'contacts' 状态匹配 "/contacts"
  • 'contacts.list' state matches "/list". The urls were not combined because ^ was used.
    url'contacts.list' 状态匹配"/list",现在url没有被组合在一起,因为使用了'^'符号。

$stateParams Service
$stateParams服务

As you saw previously the $stateParams service is an object that will have one key per url parameter. The $stateParams is a perfect way to provide your controllers or other services with the individual parts of the navigated url.
正如您之前看到的,$stateParams服务是一个对象,每个url参数都有一个键。$stateParams是为您的控制器或其他服务提供导航url的各个部分的完美方式。

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.
注意:$stateParams服务必须指定为状态控制器为作用域,因此只有在该状态中定义的相关参数在服务对象中可用。

// 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' }

Important $stateParams Gotcha
$stateParams主要问题

In state controllers, the $stateParams object will only contain the params that were registered with that state. So you will not see params registered on other states, including ancestors.
在状态控制器中,$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! ***//  
   }
})

Instead, use a resolve statement in the parent route.
相反,在父路由中使用解析(resolve)语句。

$stateProvider.state('contacts.detail', {
   url: '/contacts/:contactId',   
   controller: function($stateParams){
      $stateParams.contactId  //*** Exists! ***//
   },
   resolve:{
      contactId: ['$stateParams', function($stateParams){
          return $stateParams.contactId;
      }]
   }
}).state('contacts.detail.subitem', {
   url: '/item/:itemId', 
   controller: function($stateParams, contactId){
      contactId //*** Exists! ***//
      $stateParams.itemId //*** Exists! ***//  
   }
})

$urlRouterProvider

$urlRouterProvider has the responsibility of watching $location. When $location changes it runs through a list of rules one by one until a match is found. $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有责任观察$location。当$location改变时,它会遍历规则列表直到找到匹配为止。当您在状态配置中指定url时,$urlRouterProvider在后台所所有的url都被编译成一个UrlMatcher对象(请参阅下面的$urlMatcherFactory)。

There are several methods on $urlRouterProvider that make it useful to use directly in your module config.
$urlRouterProvider上有几个方法,可以使它在模块配置中直接使用。

when() for redirection

Parameters:
参数:

  • what String | RegExp | UrlMatcher 您想要重定向的源路径。
  • handler String | Function 您希望将用户重定向到的目标路径。

handler 作为字符串类型时

If handler is a string, it is treated as a redirect, and is interpolated according to the syntax of match (i.e. like String.replace() for RegExp, or like a UrlMatcher pattern otherwise).
如果handler是字符串,则将其视为重定向,并根据match的语法进行插值(例如,用于RegExp的string.replace(),或者类似于UrlMatcher模式)。

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 作为函数时

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
如果handler是一个函数,它是可注入的。如果$location匹配,就会调用它。您可以选择将匹配对象注入$match

handler可以返回::

  • falsy to indicate that the rule didn't match after all, then $urlRouter will continue trying to find another one that matches. 
    falsy表明这条规则根本不匹配,于是url路由器将继续寻找匹配的另一个。
  • String, which is treated as a redirect and passed to $location.url()
    一个字符串,它被视为重定向,并传递给$location.url()
  • nothing or any truthy value tells $urlRouter that the url was handled
    nothing 或任何 truthy值,意思告诉 $urlRouter 该 url 已被处理

Here's the actual code that we use to register state's that have urls behind the scenes.
下面是我们用来注册状态的代码,在后台有url。

$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
otherwise为无效的路由重定向

Parameters:
参数

  • path String | Function The url path you want to redirect to or a function rule that returns the url path. The function version is passed two params: $injector and $location.
    path String | Function 您想要重定向的url路径,或者返回url路径的函数。函数版本有两个参数:$injector和$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
rule()用于自定义处理url规则

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.
    handler Function 一个函数,它接受$injector和$location服务作为参数。函数需要返回一条有效字符串路由。
app.config(function ($urlRouterProvider) {
   // Here's an example of how you might allow case insensitive urls
   // Note that this is an example, and you may also use 
   // $urlMatcherFactory.caseInsensitive(true); for a similar result.
   $urlRouterProvider.rule(function ($injector, $location) {
       //what this function returns will be set as the $location.url
        var path = $location.path(), normalized = path.toLowerCase();
        if (path != normalized) {
            //instead of returning a new url string, I'll just change the $location.path directly so I don't have to worry about constructing a new url string and so a new state change is not triggered
            $location.replace().path(normalized);
        }
        // because we've returned nothing, no state change occurs
    });
})

$urlMatcherFactory and UrlMatchers
$urlMatcherFactory 和 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.
定义url模式和参数占位符的语法。该工厂服务在后台使用$urlRouterProvider来缓存已编译的UrlMatcher对象,当url更改时而不必重新解析位置。大多数用户不需要直接使用$urlMatcherFactory,但是它可以很好地创建一个UrlMatcher对象并将其作为url传递给状态配置。

Please refer to the comment documentation within the $urlMatcherFactory file to learn more.
请参阅$urlMatcherFactory文件中的注释文档以了解更多信息。

var urlMatcher = $urlMatcherFactory.compile("/home/:id?param1");
$stateProvider.state('myState', {
    url: urlMatcher 
});

探讨请加微信:


相关文章推荐

angular 使用 ui-router 设计网页

这篇文章主要介绍了angular中如果使用ui-router使用,并总结了一些常见的用法
  • fansongy
  • fansongy
  • 2015年03月09日 23:06
  • 48452

angular ui-router 路由默认跳转语句$urlRouterProvider.otherwise(‘路径');与<a>共用时存在的问题

当angular路由设置默认跳转路径$urlRouterProvider.otherwise(‘default'),并且页面存在标签并且标签设置属性href="###"即时,每次点击标签都会跳转到‘’...
  • bem_zj
  • bem_zj
  • 2017年05月21日 22:16
  • 2518

angular ui-router:简单的单页面嵌套路由的实现过程

写在前面: ui-router是angular的一个插件,因为angular前面几个版本自带的原生ng-router不能很好的满足开发需求,所以在实现angular单页面嵌套的时候,都是使用ui-r...
  • OBKoro1
  • OBKoro1
  • 2017年06月05日 00:42
  • 1996

Angular学习-ng-route与ui-router路由的区别

什么是路由? 路由是AngularJS构建单页面应用的基础。 路由,就是网络数据或者请求进行分发的一个网络组件。 路由就是一个用于请求URL分发和跳转的一个应用组件,Angular中通过$rou...

Angular路由 ng-route和ui-router的区别

什么是路由? 路由是AngularJS构建单页面应用的基础。 路由,就是网络数据或者请求进行分发的一个网络组件。 路由就是一个用于请求URL分发和跳转的一个应用组件,Angular中...

UI-Router:为什么开发者都不喜欢Angular.js内置的路由

UI-Router:为什么开发者都不喜欢Angular.js内置的路由 字数5012 阅读4366 评论7 喜欢10 Angular.js 是一个用来构建“富客户端”的神奇JavaSc...

angular 系列七 ui-router路由控制器介绍

angularUI 在不断发展过程中已经被划分成了几个模块,你可以选择你需要的模块载入,我们今天要了解一下路由控制器 ui-router ,它就是angularUI划分出出来的一个独立模块. ...

UI-Router:为什么开发者都不喜欢Angular.js内置的路由

Angular.js 是一个用来构建“富客户端”的神奇JavaScript框架。但是事实却是许多开发者却不使用其内置的路由模块。反而使用AngularUI项目的 UI-Router模块来代替之。这是因...

AngularJS学习笔记--002--Angular JS路由插件ui.router源码解析

路由(route),几乎所有的MVC(VM)框架都应该具有的特性,因为它是前端构建单页面应用(SPA)必不可少的组成部分。 那么,对于angular而言,它自然也有内置的路由模块:叫做n...
  • wxl1555
  • wxl1555
  • 2016年12月13日 13:34
  • 221

Angular ui-router同时加载多个视图,根据不同url在同一个视图切换内容模板

Angular ui-router同时加载多个视图,根据不同url在同一个视图切换内容模板。目的:点击sidebar切换在container中切换视图 入口页面 index.html 包含一个没名u...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:4、Angular-Ui Router URL路由(完结篇)
举报原因:
原因补充:

(最多只允许输入30个字)