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


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


需要命理預測服務請加微信:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章