2016-06-23 09:47:54 -07:00
|
|
|
|
/**
|
|
|
|
|
* @license
|
|
|
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
|
*/
|
|
|
|
|
|
2017-04-05 02:00:40 +03:00
|
|
|
|
import {NgModuleFactory, NgModuleRef, Type} from '@angular/core';
|
2018-02-27 17:06:06 -05:00
|
|
|
|
import {Observable} from 'rxjs';
|
2018-12-14 14:02:50 -05:00
|
|
|
|
|
2018-04-06 15:56:36 -07:00
|
|
|
|
import {EmptyOutletComponent} from './components/empty_outlet';
|
2018-12-14 14:02:50 -05:00
|
|
|
|
import {ActivatedRouteSnapshot} from './router_state';
|
2016-12-02 14:09:09 -08:00
|
|
|
|
import {PRIMARY_OUTLET} from './shared';
|
2016-11-09 15:25:47 -08:00
|
|
|
|
import {UrlSegment, UrlSegmentGroup} from './url_tree';
|
2016-08-19 17:48:09 -05:00
|
|
|
|
|
2018-12-14 14:02:50 -05:00
|
|
|
|
|
2016-06-27 12:27:23 -07:00
|
|
|
|
/**
|
2016-09-10 16:52:21 -07:00
|
|
|
|
* @description
|
2018-04-05 11:51:21 +01:00
|
|
|
|
*
|
|
|
|
|
* Represents router configuration.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 表示路由器配置。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* `Routes` is an array of route configurations. Each one has the following properties:
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* `Routes` 是个表示路由配置的数组。每一个都具有下列属性:
|
|
|
|
|
*
|
2016-09-10 16:52:21 -07:00
|
|
|
|
* - `path` is a string that uses the route matcher DSL.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `path` 是一个用于路由匹配 DSL 中的字符串。
|
|
|
|
|
*
|
2019-01-15 09:35:27 -08:00
|
|
|
|
* - `pathMatch` is a string that specifies the matching strategy. Options are `prefix` (default)
|
|
|
|
|
* and `full`. See [Matching Strategy](#matching-strategy) below for more information.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
2019-02-17 00:00:16 +08:00
|
|
|
|
* `pathMatch`是一个用来指定路由匹配策略的字符串。可选项有 `prefix`(默认值)和 `full`。参见[匹配策略](#matching-strategy)部分,以了解更多知识。
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* - `matcher` defines a custom strategy for path matching and supersedes `path` and `pathMatch`.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `matcher` 定义了一个用于路径匹配的自定义策略,指定了它就会代替 `path` 和 `pathMatch`。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* - `component` is a component type.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `component` 是一个组件类型。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* - `redirectTo` is the url fragment which will replace the current matched segment.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `redirectTo` 是一个 URL 片段,它将会代替当前匹配的 URL 片段。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* - `outlet` is the name of the outlet the component should be placed into.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `outlet` 是该组件要放进的出口的名字。
|
|
|
|
|
*
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* - `canActivate` is an array of DI tokens used to look up CanActivate handlers. See
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* `CanActivate` for more info.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `canActivate` 是一个 DI 令牌的数组,用于查阅 `CanActivate` 处理器,欲知详情,参见 `CanActivate`。
|
|
|
|
|
*
|
2016-07-13 15:25:48 -07:00
|
|
|
|
* - `canActivateChild` is an array of DI tokens used to look up CanActivateChild handlers. See
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* `CanActivateChild` for more info.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `canActivateChild` 是一个 DI 令牌的数组,用于查阅 `CanActivateChild` 处理器,欲知详情,参见 `CanActivateChild`。
|
|
|
|
|
*
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* - `canDeactivate` is an array of DI tokens used to look up CanDeactivate handlers. See
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* `CanDeactivate` for more info.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `canDeactivate` 是一个 DI 令牌的数组,用于查阅 `CanDeactivate` 处理器,欲知详情,参见 `CanDeactivate`。
|
|
|
|
|
*
|
2017-05-10 19:34:34 -04:00
|
|
|
|
* - `canLoad` is an array of DI tokens used to look up CanLoad handlers. See
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* `CanLoad` for more info.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `canLoad` 是一个 DI 令牌的数组,用于查阅 `CanLoad` 处理器,欲知详情,参见 `CanLoad`。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* - `data` is additional data provided to the component via `ActivatedRoute`.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `data` 是一个可通过 `ActivatedRoute` 提供给组件的附加数据。
|
|
|
|
|
*
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* - `resolve` is a map of DI tokens used to look up data resolvers. See `Resolve` for more
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* info.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `resolve` 是一个 DI 令牌的映射表,用于查阅数据解析器。欲知详情,参见 `Resolve`。
|
|
|
|
|
*
|
2017-06-04 23:32:46 -03:00
|
|
|
|
* - `runGuardsAndResolvers` defines when guards and resolvers will be run. By default they run only
|
2018-10-30 14:13:55 -07:00
|
|
|
|
* when the matrix parameters of the route change. Options include:
|
|
|
|
|
* - `paramsChange` (default) - Run guards and resolvers when path or matrix params change. This
|
|
|
|
|
* mode ignores query param changes.
|
|
|
|
|
* - `paramsOrQueryParamsChange` - Guards and resolvers will run when any parameters change. This
|
|
|
|
|
* includes path, matrix, and query params.
|
2018-12-04 13:49:12 -08:00
|
|
|
|
* - `pathParamsChange` - Run guards and resolvers path or any path params change. This mode is
|
2018-10-30 14:13:55 -07:00
|
|
|
|
* useful if you want to ignore changes to all optional parameters such as query *and* matrix
|
|
|
|
|
* params.
|
2018-12-04 13:49:12 -08:00
|
|
|
|
* - `pathParamsOrQueryParamsChange` - Same as `pathParamsChange`, but also rerun when any query
|
|
|
|
|
* param changes
|
2018-10-30 14:13:55 -07:00
|
|
|
|
* - `always` - Run guards and resolvers on every navigation.
|
2018-12-14 14:02:50 -05:00
|
|
|
|
* - (from: ActivatedRouteSnapshot, to: ActivatedRouteSnapshot) => boolean - Use a predicate
|
|
|
|
|
* function when none of the pre-configured modes fit the needs of the application. An example
|
|
|
|
|
* might be when you need to ignore updates to a param such as `sortDirection`, but need to
|
|
|
|
|
* reload guards and resolvers when changing the `searchRoot` param.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `runGuardsAndResolvers` 定义了路由守卫和解析器的运行时机。默认情况下,它们只会在路由的矩阵参数(`#`)变化时才会执行。
|
|
|
|
|
* 当设置为 `paramsOrQueryParamsChange` 时,它们在查询参数(`?`)变化时也会执行。当设置为 `always` 时,它们每次都会执行。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* - `children` is an array of child route definitions.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `children` 是一个子路由定义构成的数组。
|
|
|
|
|
*
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* - `loadChildren` is a reference to lazy loaded child routes. See `LoadChildren` for more
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* info.
|
2016-07-06 16:19:52 -07:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* `loadChildren` 是一个用于惰性加载子路由的引用。欲知详情,参见 `LoadChildren`。
|
|
|
|
|
*
|
2018-09-20 14:50:32 +01:00
|
|
|
|
* @usageNotes
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ### Simple Configuration
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* ### 简单配置
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: 'team/:id',
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* component: Team,
|
|
|
|
|
* children: [{
|
|
|
|
|
* path: 'user/:name',
|
|
|
|
|
* component: User
|
|
|
|
|
* }]
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* When navigating to `/team/11/user/bob`, the router will create the team component with the user
|
|
|
|
|
* component in it.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 当导航到 `/team/11/user/bob` 时,路由器将会创建一个 Team 组件,其中包含一个 User 组件。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ### Multiple Outlets
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* ### 多重路由出口
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: 'team/:id',
|
|
|
|
|
* component: Team
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* }, {
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* path: 'chat/:user',
|
|
|
|
|
* component: Chat
|
2016-09-28 01:10:12 +08:00
|
|
|
|
* outlet: 'aux'
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* When navigating to `/team/11(aux:chat/jim)`, the router will create the team component next to
|
|
|
|
|
* the chat component. The chat component will be placed into the aux outlet.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 在导航到 `/team/11(aux:chat/jim)` 时,路由器将会在创建了 Chat 组件之后创建一个 Team 组件。Chat 组件会被放进 `aux` 路由出口中。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ### Wild Cards
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* ### 通配符
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: '**',
|
|
|
|
|
* component: Sink
|
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* Regardless of where you navigate to, the router will instantiate the sink component.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 无论你导航到哪里,路由器都会实例化这个 Sink 组件。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ### Redirects
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* ### 重定向
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: 'team/:id',
|
|
|
|
|
* component: Team,
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* children: [{
|
|
|
|
|
* path: 'legacy/user/:name',
|
|
|
|
|
* redirectTo: 'user/:name'
|
|
|
|
|
* }, {
|
|
|
|
|
* path: 'user/:name',
|
|
|
|
|
* component: User
|
|
|
|
|
* }]
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* When navigating to '/team/11/legacy/user/jim', the router will change the url to
|
|
|
|
|
* '/team/11/user/jim', and then will instantiate the team component with the user component
|
|
|
|
|
* in it.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 当导航到 '/team/11/legacy/user/jim' 时,路由器将会把 URL 改成 '/team/11/user/jim',然后实例化一个 Team 组件,其中包含一个 User 组件。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* If the `redirectTo` value starts with a '/', then it is an absolute redirect. E.g., if in the
|
|
|
|
|
* example above we change the `redirectTo` to `/user/:name`, the result url will be '/user/jim'.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 如果 `redirectTo` 的值是以 `/` 开头的,则会执行一次绝对导航。比如,如果上面的例子中我们把 `redirectTo` 改为 `/user/:name`,
|
|
|
|
|
* 那么最终的 url 就会是 `'/user/jim'`。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ### Empty Path
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* ### 空路径
|
|
|
|
|
*
|
2016-09-10 16:52:21 -07:00
|
|
|
|
* Empty-path route configurations can be used to instantiate components that do not 'consume'
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* any url segments. Let's look at the following configuration:
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 空路径路由可用来实例化一些不"消费"任何 url 区段的组件。来看下列配置:
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: 'team/:id',
|
|
|
|
|
* component: Team,
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* children: [{
|
|
|
|
|
* path: '',
|
|
|
|
|
* component: AllUsers
|
|
|
|
|
* }, {
|
|
|
|
|
* path: 'user/:name',
|
|
|
|
|
* component: User
|
|
|
|
|
* }]
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* When navigating to `/team/11`, the router will instantiate the AllUsers component.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 当导航到 `/team/11` 时,路由器就会实例化 AllUsers 组件。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* Empty-path routes can have children.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 空路径路由还可以有子路由。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: 'team/:id',
|
|
|
|
|
* component: Team,
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* children: [{
|
|
|
|
|
* path: '',
|
|
|
|
|
* component: WrapperCmp,
|
|
|
|
|
* children: [{
|
|
|
|
|
* path: 'user/:name',
|
|
|
|
|
* component: User
|
|
|
|
|
* }]
|
|
|
|
|
* }]
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* When navigating to `/team/11/user/jim`, the router will instantiate the wrapper component with
|
|
|
|
|
* the user component in it.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 当导航到 `/team/11/user/jim` 时,路由器将会实例化 `WrapperCmp`,其中还有一个 `User` 组件。
|
|
|
|
|
*
|
2016-11-15 19:00:20 -08:00
|
|
|
|
* An empty path route inherits its parent's params and data. This is because it cannot have its
|
|
|
|
|
* own params, and, as a result, it often uses its parent's params and data as its own.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 空路径路由会继承它的父路由的参数和数据。这是因为它不能拥有自己的参数,所以,它通常会把其父路由的参数和数据当做自己的使用。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ### Matching Strategy
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* ### 匹配策略
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* By default the router will look at what is left in the url, and check if it starts with
|
|
|
|
|
* the specified path (e.g., `/team/11/user` starts with `team/:id`).
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 默认情况下,路由器会查看当前 URL 中还剩下什么,并检查它是否以指定的路径开头(比如 `/team/11/user` 就是用 `team/:id` 开头的)。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* We can change the matching strategy to make sure that the path covers the whole unconsumed url,
|
|
|
|
|
* which is akin to `unconsumedUrl === path` or `$` regular expressions.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 我们可以修改匹配策略,以确保该路径匹配所有尚未消费的 url,它相当于 `unconsumedUrl === path` 或正则表达式中的 `$`。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* This is particularly important when redirecting empty-path routes.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 如果要把空路径路由重定向到别处,这尤其重要。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: '',
|
|
|
|
|
* pathMatch: 'prefix', //default
|
|
|
|
|
* redirectTo: 'main'
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* }, {
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* path: 'main',
|
|
|
|
|
* component: Main
|
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* Since an empty path is a prefix of any url, even when navigating to '/main', the router will
|
|
|
|
|
* still apply the redirect.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 由于空路径是任何 url 的前缀,所以即使想导航到 '/main',路由器仍然会执行这次跳转。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* If `pathMatch: full` is provided, the router will apply the redirect if and only if navigating to
|
|
|
|
|
* '/'.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 如果指定了 `pathMatch: full`,则路由器只有在导航到 `'/'` 时才会执行这次跳转。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: '',
|
|
|
|
|
* pathMatch: 'full',
|
|
|
|
|
* redirectTo: 'main'
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* }, {
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* path: 'main',
|
|
|
|
|
* component: Main
|
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* ### Componentless Routes
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* ### 无组件路由
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* It is useful at times to have the ability to share parameters between sibling components.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 当需要在兄弟组件之间共享参数时,这非常有用。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* Say we have two components--ChildCmp and AuxCmp--that we want to put next to each other and both
|
|
|
|
|
* of them require some id parameter.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 假设我们有两个组件 `ChildCmp` 和 `AuxCmp`,它们彼此相邻,并且都需要一个 `id` 参数。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* One way to do that would be to have a bogus parent component, so both the siblings can get the id
|
|
|
|
|
* parameter from it. This is not ideal. Instead, you can use a componentless route.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 解决方案之一就是伪造一个父组件,这样一来,这些兄弟组件就可以通过它获取同一个 id 参数了。但这还不理想。我们要改用无组件路由。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: 'parent/:id',
|
|
|
|
|
* children: [
|
|
|
|
|
* { path: 'a', component: MainChild },
|
|
|
|
|
* { path: 'b', component: AuxChild, outlet: 'aux' }
|
|
|
|
|
* ]
|
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* So when navigating to `parent/10/(a//aux:b)`, the route will instantiate the main child and aux
|
|
|
|
|
* child components next to each other. In this example, the application component
|
|
|
|
|
* has to have the primary and aux outlets defined.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 这样当导航到 `parent/10/(a//aux:b)` 时,该路由将会先后实例化主要的子控件和辅助子控件。在这个例子中,应用组件必须定义主路由出口和 `aux` 出口。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* The router will also merge the `params`, `data`, and `resolve` of the componentless parent into
|
2016-11-15 19:00:20 -08:00
|
|
|
|
* the `params`, `data`, and `resolve` of the children. This is done because there is no component
|
|
|
|
|
* that can inject the activated route of the componentless parent.
|
2016-07-06 16:19:52 -07:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 路由器还会把这个无组件父路由的 `params`、`data` 和 `resolve` 结果合并到子路由的 `params`、`data` 和 `resolve` 中。
|
|
|
|
|
* 之所以能这样,是因为这里没有组件能接收这个无组件父路由的激活路由信息,所以只能合并到子路由中。
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* This is especially useful when child components are defined as follows:
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 当用如下方式定义子组件时,这会非常有用:
|
|
|
|
|
*
|
2016-07-06 16:19:52 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: 'parent/:id',
|
|
|
|
|
* children: [
|
|
|
|
|
* { path: '', component: MainChild },
|
|
|
|
|
* { path: '', component: AuxChild, outlet: 'aux' }
|
|
|
|
|
* ]
|
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* With this configuration in place, navigating to '/parent/10' will create the main child and aux
|
|
|
|
|
* components.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 使用这种配置,导航到 '/parent/10' 时就会创建主要的子组件和辅助子组件。
|
|
|
|
|
*
|
2016-09-10 16:52:21 -07:00
|
|
|
|
* ### Lazy Loading
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* ### 惰性加载
|
|
|
|
|
*
|
2016-09-10 16:52:21 -07:00
|
|
|
|
* Lazy loading speeds up our application load time by splitting it into multiple bundles, and
|
|
|
|
|
* loading them on demand. The router is designed to make lazy loading simple and easy. Instead of
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* providing the children property, you can provide the `loadChildren` property, as follows:
|
2016-09-10 16:52:21 -07:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 惰性加载可以通过把应用拆分成多个发布包,并按需加载它们,来加速应用的启动时间。
|
|
|
|
|
* 路由器的设计让惰性加载非常简易。只要用 `loadChildren` 属性代替 `children` 属性就可以了,例如:
|
|
|
|
|
*
|
2016-09-10 16:52:21 -07:00
|
|
|
|
* ```
|
|
|
|
|
* [{
|
|
|
|
|
* path: 'team/:id',
|
|
|
|
|
* component: Team,
|
|
|
|
|
* loadChildren: 'team'
|
|
|
|
|
* }]
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* The router will use registered NgModuleFactoryLoader to fetch an NgModule associated with 'team'.
|
2016-12-02 14:09:09 -08:00
|
|
|
|
* Then it will extract the set of routes defined in that NgModule, and will transparently add
|
|
|
|
|
* those routes to the main configuration.
|
2016-09-10 16:52:21 -07:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 路由器会使用已注册的 `NgModuleFactoryLoader` 来获取与 `team` 相关的 NgModule。
|
|
|
|
|
* 然后,它就会提取出那个 NgModule 中定义的一组路由,并透明的把那些路由添加到主路由配置中。
|
|
|
|
|
*
|
2018-10-19 18:25:11 +01:00
|
|
|
|
* @publicApi
|
2016-07-06 16:19:52 -07:00
|
|
|
|
*/
|
|
|
|
|
export type Routes = Route[];
|
|
|
|
|
|
2016-11-09 15:25:47 -08:00
|
|
|
|
/**
|
2018-04-05 11:51:21 +01:00
|
|
|
|
* @description Represents the results of the URL matching.
|
2016-11-09 15:25:47 -08:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 表示 URL 匹配的结果。
|
|
|
|
|
*
|
2016-11-09 15:25:47 -08:00
|
|
|
|
* * `consumed` is an array of the consumed URL segments.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* `consumed` 是一个已消费的 URL 区段的数组。
|
|
|
|
|
*
|
2016-11-09 15:25:47 -08:00
|
|
|
|
* * `posParams` is a map of positional parameters.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* `posParams` 是位置参数的映射表。
|
|
|
|
|
*
|
2018-10-19 12:12:20 +01:00
|
|
|
|
* @publicApi
|
2016-11-09 15:25:47 -08:00
|
|
|
|
*/
|
|
|
|
|
export type UrlMatchResult = {
|
|
|
|
|
consumed: UrlSegment[]; posParams?: {[name: string]: UrlSegment};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description
|
|
|
|
|
*
|
2018-04-05 11:51:21 +01:00
|
|
|
|
* A function matching URLs
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 用于匹配 URL 的函数
|
|
|
|
|
*
|
2016-11-09 15:25:47 -08:00
|
|
|
|
* A custom URL matcher can be provided when a combination of `path` and `pathMatch` isn't
|
|
|
|
|
* expressive enough.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 当 `path` 和 `pathMatch` 的组合无法满足需求时,可以提供一个自定义的 URL 匹配器。
|
|
|
|
|
*
|
2016-11-09 15:25:47 -08:00
|
|
|
|
* For instance, the following matcher matches html files.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 比如,下列匹配器会匹配 html 文件。
|
|
|
|
|
*
|
2016-11-09 15:25:47 -08:00
|
|
|
|
* ```
|
2017-12-19 15:53:22 -08:00
|
|
|
|
* export function htmlFiles(url: UrlSegment[]) {
|
|
|
|
|
* return url.length === 1 && url[0].path.endsWith('.html') ? ({consumed: url}) : null;
|
2016-11-09 15:25:47 -08:00
|
|
|
|
* }
|
|
|
|
|
*
|
2017-12-19 15:53:22 -08:00
|
|
|
|
* export const routes = [{ matcher: htmlFiles, component: AnyComponent }];
|
2016-11-09 15:25:47 -08:00
|
|
|
|
* ```
|
|
|
|
|
*
|
2018-10-19 12:12:20 +01:00
|
|
|
|
* @publicApi
|
2016-11-09 15:25:47 -08:00
|
|
|
|
*/
|
|
|
|
|
export type UrlMatcher = (segments: UrlSegment[], group: UrlSegmentGroup, route: Route) =>
|
|
|
|
|
UrlMatchResult;
|
|
|
|
|
|
2016-07-06 16:19:52 -07:00
|
|
|
|
/**
|
2018-04-05 11:51:21 +01:00
|
|
|
|
* @description
|
|
|
|
|
*
|
|
|
|
|
* Represents the static data associated with a particular route.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 表示与特定路由相关的静态数据。
|
|
|
|
|
*
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* See `Routes` for more details.
|
2018-04-05 22:31:44 +01:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 欲知详情,参见 `Routes`。
|
|
|
|
|
*
|
2018-10-19 18:25:11 +01:00
|
|
|
|
* @publicApi
|
2016-06-27 12:27:23 -07:00
|
|
|
|
*/
|
2016-06-27 14:00:07 -07:00
|
|
|
|
export type Data = {
|
|
|
|
|
[name: string]: any
|
|
|
|
|
};
|
2016-06-27 12:27:23 -07:00
|
|
|
|
|
|
|
|
|
/**
|
2018-04-05 11:51:21 +01:00
|
|
|
|
* @description
|
|
|
|
|
*
|
|
|
|
|
* Represents the resolved data associated with a particular route.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 表示与特定路由相关的解析出来的数据。
|
|
|
|
|
*
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* See `Routes` for more details.
|
2018-04-05 22:31:44 +01:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 欲知详情,参见 `Routes`。
|
|
|
|
|
*
|
2018-10-19 18:25:11 +01:00
|
|
|
|
* @publicApi
|
2016-06-27 12:27:23 -07:00
|
|
|
|
*/
|
2016-06-27 14:00:07 -07:00
|
|
|
|
export type ResolveData = {
|
|
|
|
|
[name: string]: any
|
|
|
|
|
};
|
2016-05-23 16:14:23 -07:00
|
|
|
|
|
2016-08-15 21:11:09 -07:00
|
|
|
|
/**
|
2018-04-05 11:51:21 +01:00
|
|
|
|
* @description
|
|
|
|
|
*
|
|
|
|
|
* The type of `loadChildren`.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* `loadChildren` 的类型定义。
|
|
|
|
|
*
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* See `Routes` for more details.
|
2018-04-05 22:31:44 +01:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 欲知详情,参见 `Routes`。
|
|
|
|
|
*
|
2018-10-19 18:25:11 +01:00
|
|
|
|
* @publicApi
|
2016-08-15 21:11:09 -07:00
|
|
|
|
*/
|
2017-01-19 02:56:34 +03:00
|
|
|
|
export type LoadChildrenCallback = () =>
|
|
|
|
|
Type<any>| NgModuleFactory<any>| Promise<Type<any>>| Observable<Type<any>>;
|
2016-08-15 21:11:09 -07:00
|
|
|
|
|
|
|
|
|
/**
|
2018-04-05 11:51:21 +01:00
|
|
|
|
* @description
|
|
|
|
|
*
|
|
|
|
|
* The type of `loadChildren`.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* `loadChildren` 的类型定义。
|
|
|
|
|
*
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* See `Routes` for more details.
|
2018-04-05 22:31:44 +01:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 欲知详情,参见 `Routes`。
|
2018-10-19 18:25:11 +01:00
|
|
|
|
* @publicApi
|
2016-08-15 21:11:09 -07:00
|
|
|
|
*/
|
|
|
|
|
export type LoadChildren = string | LoadChildrenCallback;
|
|
|
|
|
|
2017-01-25 17:33:13 +08:00
|
|
|
|
/**
|
2018-04-05 11:51:21 +01:00
|
|
|
|
* @description
|
|
|
|
|
*
|
|
|
|
|
* The type of `queryParamsHandling`.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* `queryParamsHandling` 的类型定义。
|
|
|
|
|
*
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* See `RouterLink` for more details.
|
2018-04-05 22:31:44 +01:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 欲知详情,参见 `RouterLink`。
|
2017-01-25 17:33:13 +08:00
|
|
|
|
*/
|
|
|
|
|
export type QueryParamsHandling = 'merge' | 'preserve' | '';
|
|
|
|
|
|
2017-02-23 22:12:30 -08:00
|
|
|
|
/**
|
2018-04-05 11:51:21 +01:00
|
|
|
|
* @description
|
|
|
|
|
*
|
|
|
|
|
* The type of `runGuardsAndResolvers`.
|
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* `runGuardsAndResolvers` 的类型定义。
|
|
|
|
|
*
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* See `Routes` for more details.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* 欲知详情,参见 `Routes`。
|
|
|
|
|
*
|
2018-10-19 12:12:20 +01:00
|
|
|
|
* @publicApi
|
2017-02-23 22:12:30 -08:00
|
|
|
|
*/
|
2018-12-04 13:49:12 -08:00
|
|
|
|
export type RunGuardsAndResolvers = 'pathParamsChange' | 'pathParamsOrQueryParamsChange' |
|
2018-12-14 14:02:50 -05:00
|
|
|
|
'paramsChange' | 'paramsOrQueryParamsChange' | 'always' |
|
|
|
|
|
((from: ActivatedRouteSnapshot, to: ActivatedRouteSnapshot) => boolean);
|
2017-02-23 22:12:30 -08:00
|
|
|
|
|
2016-06-27 12:27:23 -07:00
|
|
|
|
/**
|
2018-04-05 11:53:57 +01:00
|
|
|
|
* See `Routes` for more details.
|
2018-04-05 22:31:44 +01:00
|
|
|
|
*
|
2018-09-01 13:07:46 +08:00
|
|
|
|
* 欲知详情,参见 `Routes`。
|
|
|
|
|
*
|
2018-10-19 18:25:11 +01:00
|
|
|
|
* @publicApi
|
2016-06-27 12:27:23 -07:00
|
|
|
|
*/
|
2016-05-23 16:14:23 -07:00
|
|
|
|
export interface Route {
|
|
|
|
|
path?: string;
|
2016-07-28 12:15:07 -07:00
|
|
|
|
pathMatch?: string;
|
2016-11-09 15:25:47 -08:00
|
|
|
|
matcher?: UrlMatcher;
|
2016-08-16 13:40:28 -07:00
|
|
|
|
component?: Type<any>;
|
2016-06-28 14:49:29 -07:00
|
|
|
|
redirectTo?: string;
|
2016-05-23 16:14:23 -07:00
|
|
|
|
outlet?: string;
|
2016-06-07 09:50:35 -07:00
|
|
|
|
canActivate?: any[];
|
2016-07-13 15:15:20 -07:00
|
|
|
|
canActivateChild?: any[];
|
2016-06-07 09:50:35 -07:00
|
|
|
|
canDeactivate?: any[];
|
2016-07-26 14:39:02 -07:00
|
|
|
|
canLoad?: any[];
|
2016-06-27 14:00:07 -07:00
|
|
|
|
data?: Data;
|
|
|
|
|
resolve?: ResolveData;
|
2016-12-06 21:41:01 +03:00
|
|
|
|
children?: Routes;
|
2016-08-15 21:11:09 -07:00
|
|
|
|
loadChildren?: LoadChildren;
|
2017-02-23 22:12:30 -08:00
|
|
|
|
runGuardsAndResolvers?: RunGuardsAndResolvers;
|
2017-04-11 08:34:58 -07:00
|
|
|
|
/**
|
|
|
|
|
* Filled for routes with `loadChildren` once the module has been loaded
|
|
|
|
|
* @internal
|
|
|
|
|
*/
|
2017-04-05 02:00:40 +03:00
|
|
|
|
_loadedConfig?: LoadedRouterConfig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class LoadedRouterConfig {
|
|
|
|
|
constructor(public routes: Route[], public module: NgModuleRef<any>) {}
|
2016-06-16 14:36:51 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 21:41:01 +03:00
|
|
|
|
export function validateConfig(config: Routes, parentPath: string = ''): void {
|
2016-11-11 01:55:10 +03:00
|
|
|
|
// forEach doesn't iterate undefined values
|
|
|
|
|
for (let i = 0; i < config.length; i++) {
|
2016-12-06 21:41:01 +03:00
|
|
|
|
const route: Route = config[i];
|
|
|
|
|
const fullPath: string = getFullPath(parentPath, route);
|
|
|
|
|
validateNode(route, fullPath);
|
2016-11-11 01:55:10 +03:00
|
|
|
|
}
|
2016-06-16 14:36:51 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 21:41:01 +03:00
|
|
|
|
function validateNode(route: Route, fullPath: string): void {
|
2016-11-11 01:55:10 +03:00
|
|
|
|
if (!route) {
|
|
|
|
|
throw new Error(`
|
2016-12-06 21:41:01 +03:00
|
|
|
|
Invalid configuration of route '${fullPath}': Encountered undefined route.
|
2016-11-11 01:55:10 +03:00
|
|
|
|
The reason might be an extra comma.
|
2017-02-23 22:12:30 -08:00
|
|
|
|
|
|
|
|
|
Example:
|
2016-11-11 01:55:10 +03:00
|
|
|
|
const routes: Routes = [
|
|
|
|
|
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
|
|
|
|
|
{ path: 'dashboard', component: DashboardComponent },, << two commas
|
|
|
|
|
{ path: 'detail/:id', component: HeroDetailComponent }
|
|
|
|
|
];
|
|
|
|
|
`);
|
|
|
|
|
}
|
2016-07-15 00:28:31 +09:00
|
|
|
|
if (Array.isArray(route)) {
|
2016-12-06 21:41:01 +03:00
|
|
|
|
throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
|
2016-07-15 00:28:31 +09:00
|
|
|
|
}
|
2018-04-06 15:56:36 -07:00
|
|
|
|
if (!route.component && !route.children && !route.loadChildren &&
|
|
|
|
|
(route.outlet && route.outlet !== PRIMARY_OUTLET)) {
|
2016-10-20 15:00:15 -07:00
|
|
|
|
throw new Error(
|
2018-04-06 15:56:36 -07:00
|
|
|
|
`Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
|
2016-10-20 15:00:15 -07:00
|
|
|
|
}
|
2016-12-02 14:09:09 -08:00
|
|
|
|
if (route.redirectTo && route.children) {
|
2016-06-16 14:36:51 -07:00
|
|
|
|
throw new Error(
|
2016-12-06 21:41:01 +03:00
|
|
|
|
`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
|
2016-06-16 14:36:51 -07:00
|
|
|
|
}
|
2016-12-02 14:09:09 -08:00
|
|
|
|
if (route.redirectTo && route.loadChildren) {
|
2016-07-06 11:02:16 -07:00
|
|
|
|
throw new Error(
|
2016-12-06 21:41:01 +03:00
|
|
|
|
`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
|
2016-07-06 11:02:16 -07:00
|
|
|
|
}
|
2016-12-02 14:09:09 -08:00
|
|
|
|
if (route.children && route.loadChildren) {
|
2016-07-06 11:02:16 -07:00
|
|
|
|
throw new Error(
|
2016-12-06 21:41:01 +03:00
|
|
|
|
`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
|
2016-07-06 11:02:16 -07:00
|
|
|
|
}
|
2016-12-02 14:09:09 -08:00
|
|
|
|
if (route.redirectTo && route.component) {
|
2016-06-16 14:36:51 -07:00
|
|
|
|
throw new Error(
|
2016-12-06 21:41:01 +03:00
|
|
|
|
`Invalid configuration of route '${fullPath}': redirectTo and component cannot be used together`);
|
2016-06-16 14:36:51 -07:00
|
|
|
|
}
|
2016-12-02 14:09:09 -08:00
|
|
|
|
if (route.path && route.matcher) {
|
2016-11-09 15:25:47 -08:00
|
|
|
|
throw new Error(
|
2016-12-06 21:41:01 +03:00
|
|
|
|
`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
|
2016-11-09 15:25:47 -08:00
|
|
|
|
}
|
2016-12-02 14:09:09 -08:00
|
|
|
|
if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
|
2016-06-19 14:44:20 -07:00
|
|
|
|
throw new Error(
|
2016-12-06 21:41:01 +03:00
|
|
|
|
`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, redirectTo, children or loadChildren`);
|
2016-06-19 14:44:20 -07:00
|
|
|
|
}
|
2016-12-02 14:17:27 -08:00
|
|
|
|
if (route.path === void 0 && route.matcher === void 0) {
|
|
|
|
|
throw new Error(
|
2016-12-06 21:41:01 +03:00
|
|
|
|
`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
|
2016-06-16 14:36:51 -07:00
|
|
|
|
}
|
2016-12-02 14:17:27 -08:00
|
|
|
|
if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
|
2016-12-06 21:41:01 +03:00
|
|
|
|
throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
|
2016-06-16 14:36:51 -07:00
|
|
|
|
}
|
2016-12-02 14:09:09 -08:00
|
|
|
|
if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
|
2016-06-27 20:10:36 -07:00
|
|
|
|
const exp =
|
|
|
|
|
`The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
|
|
|
|
|
throw new Error(
|
2016-12-06 21:41:01 +03:00
|
|
|
|
`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
|
2016-06-27 20:10:36 -07:00
|
|
|
|
}
|
2016-12-02 14:09:09 -08:00
|
|
|
|
if (route.pathMatch !== void 0 && route.pathMatch !== 'full' && route.pathMatch !== 'prefix') {
|
2016-07-29 09:59:50 -07:00
|
|
|
|
throw new Error(
|
2016-12-06 21:41:01 +03:00
|
|
|
|
`Invalid configuration of route '${fullPath}': pathMatch can only be set to 'prefix' or 'full'`);
|
|
|
|
|
}
|
|
|
|
|
if (route.children) {
|
|
|
|
|
validateConfig(route.children, fullPath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getFullPath(parentPath: string, currentRoute: Route): string {
|
|
|
|
|
if (!currentRoute) {
|
|
|
|
|
return parentPath;
|
|
|
|
|
}
|
|
|
|
|
if (!parentPath && !currentRoute.path) {
|
|
|
|
|
return '';
|
|
|
|
|
} else if (parentPath && !currentRoute.path) {
|
|
|
|
|
return `${parentPath}/`;
|
|
|
|
|
} else if (!parentPath && currentRoute.path) {
|
|
|
|
|
return currentRoute.path;
|
|
|
|
|
} else {
|
|
|
|
|
return `${parentPath}/${currentRoute.path}`;
|
2016-07-29 09:59:50 -07:00
|
|
|
|
}
|
2016-06-27 12:27:23 -07:00
|
|
|
|
}
|
2018-02-21 10:21:47 -08:00
|
|
|
|
|
2018-04-06 15:56:36 -07:00
|
|
|
|
/**
|
|
|
|
|
* Makes a copy of the config and adds any default required properties.
|
2018-09-01 13:07:46 +08:00
|
|
|
|
*
|
|
|
|
|
* 制作此配置的一个副本,并补齐所有必要(required)属性的默认值。
|
|
|
|
|
*
|
2018-04-06 15:56:36 -07:00
|
|
|
|
*/
|
|
|
|
|
export function standardizeConfig(r: Route): Route {
|
|
|
|
|
const children = r.children && r.children.map(standardizeConfig);
|
|
|
|
|
const c = children ? {...r, children} : {...r};
|
|
|
|
|
if (!c.component && (children || c.loadChildren) && (c.outlet && c.outlet !== PRIMARY_OUTLET)) {
|
|
|
|
|
c.component = EmptyOutletComponent;
|
|
|
|
|
}
|
|
|
|
|
return c;
|
2018-02-27 17:06:06 -05:00
|
|
|
|
}
|