在这里,它是使用pathmatch作为完整的,当我删除这个pathmatch它甚至不加载应用程序或运行项目
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { WelcomeComponent } from './home/welcome.component';
/* Feature Modules */
import { ProductModule } from './products/product.module';
@NgModule({
imports: [
BrowserModule,
HttpModule,
RouterModule.forRoot([
{ path: 'welcome', component: WelcomeComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full' },
{ path: '**', redirectTo: 'welcome', pathMatch: 'full' }
]),
ProductModule
],
declarations: [
AppComponent,
WelcomeComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
5条答案
按热度按时间yc0p9oo01#
虽然在技术上是正确的,但其他答案将受益于Angular的URL到路由匹配的解释。如果你不知道路由器是如何工作的,我认为你不能完全(原谅这个双关语)理解**
pathMatch: full
的功能。让我们首先定义一些基本的东西。我们将使用此URL作为示例:
/users/james/articles?from=134#section
。1.这可能是显而易见的,但让我们首先指出查询参数(
?from=134
)和片段(#section
)在路径匹配中不起任何作用**。只有基本url(/users/james/articles
)才重要。/users/james/articles
的线段当然是users
、james
和articles
。1.路由器配置为具有单个根节点的 * 树 * 结构。每个**
Route
对象是一个节点,该节点可能有children
节点,而这些节点又可能有其他children
或者是叶子节点。路由器的目标是找到路由器配置 * 分支 *,从根节点开始,它将匹配所有(!!!)段的URL。”””这是至关重要的!*如果Angular没有找到匹配 * 整个 * URL的路由配置分支- * 不多不少 * -它将不会呈现 * 任何东西 。
例如,如果您的目标URL是
/a/b/c
,但路由器只能匹配**/a/b
或/a/b/c/d
,则没有匹配项,应用程序将不会呈现任何内容。最后,带有
redirectTo
的路由与常规路由的行为 * 略有 * 不同,在我看来,它们是唯一一个任何人都想使用pathMatch: full
**的地方。但我们稍后再谈这个。默认(
prefix
)路径匹配名称**
prefix
背后的原因是这样的路由配置将检查配置的path
是否是剩余URL段的前缀。但是,路由器只能匹配全段**,这使得这个命名有点混乱。无论如何,假设这是我们的根级路由器配置:
请注意,这里的每个**
Route
对象都使用默认匹配策略,即prefix
。此策略意味着路由器将遍历整个配置树,并尝试将其与目标URL进行匹配逐段**,直到URL***完全匹配***。下面是本例的实现方式:1.迭代根数组,查找第一个URL段
users
的精确匹配。'products' !== 'users'
,因此跳过该分支。请注意,我们使用的是相等性检查,而不是.startsWith()
或.includes()
-只有完整的段匹配计数!:other
匹配任何值,所以它是匹配的。但是,目标URL尚未完全匹配(我们仍然需要匹配james
和articles
),因此路由器会查找子URL。:other
的唯一子代是tricks
,也就是!== 'james'
,因此不匹配。1.然后Angular返回到根数组并从那里继续。
'user' !== 'users
,跳过分支。'users' === 'users
-段匹配。然而,这还不是完全匹配,因此我们需要查找子项(与步骤3相同)。'permissions' !== 'james'
,跳过它。:userID
匹配任何东西,因此我们有james
段的匹配。然而,这 * 仍然 * 不是完全匹配,因此我们需要寻找一个匹配articles
的子节点。1.我们可以看到
:userID
有一个子路由articles
,这给了我们一个完全匹配!因此,应用程序呈现UserArticlesComponent
。匹配完整URL(
full
)示例1
现在假设**
users
**路由配置对象如下所示:注意**
pathMatch: full
**的用法。如果是这种情况,步骤1-5将是相同的,然而步骤6将是不同的:'users' !== 'users/james/articles
-段不匹配,因为路径配置users
与pathMatch: full
不匹配完整的URL,即users/james/articles
。1.由于没有匹配项,我们将跳过此分支。
1.此时,我们到达了路由器配置的末尾,但没有找到匹配项。应用程序呈现 nothing。
示例二
如果我们用这个来代替:
users/:userID
与pathMatch: full
只匹配users/james
,因此它再次是不匹配的,并且应用程序不呈现任何内容。示例三
让我们考虑一下:
在这种情况下:
'users' === 'users
-段匹配,但james/articles
仍然不匹配。我们去找孩子吧。'permissions' !== 'james'
-跳过。:userID'
只能匹配一个片段,即james
。但是,它是一个pathMatch: full
路由,并且它必须匹配james/articles
(整个剩余的URL)。它不能做到这一点,因此它不是一个匹配(所以我们跳过这个分支)!1.同样,我们没有找到任何匹配的URL,应用程序呈现 nothing。
您可能已经注意到,
pathMatch: full
配置基本上是这样说的:别理我的孩子,只配我。如果我自己无法匹配所有 * 剩余 * URL段,则继续前进。
重定向
任何定义了**
redirectTo
的Route
都会按照相同的原则匹配到目标URL。这里唯一的区别是 * 重定向会在段匹配 * 时立即应用。这意味着如果重定向路由使用默认的prefix
**策略,则 * 部分匹配足以导致重定向 *。这里有一个很好的例子:对于我们的初始URL(
/users/james/articles
),会发生以下情况:'not-found' !== 'users'
-跳过它。'users' === 'users'
-我们有一个匹配。1.这个匹配有一个
redirectTo: 'not-found'
,它被 * 立即应用 。1.目标URL更改为
not-found
。1.路由器再次开始匹配,并立即找到
not-found
的匹配项。应用程序呈现NotFoundComponent
。现在考虑如果*
users
路由也有pathMatch: full
**会发生什么:'not-found' !== 'users'
-跳过它。users
将匹配URL的第一段,但路由配置要求full
匹配,因此跳过它。'users/:userID'
匹配users/james
。articles
仍然不匹配,但此路由有子路由。articles
的匹配。现在匹配了整个URL,应用程序呈现UserArticlesComponent
。空路径(
path: ''
)空路径有点特殊,因为它可以匹配 * 任何段*,而不会“消耗”它(因此它的子路径必须再次匹配该段)。请考虑以下示例:
假设我们正在尝试访问**
/users
**:path: ''
将始终匹配,因此路由匹配。但是,整个URL还没有匹配-我们仍然需要匹配users
!users
,它匹配剩余的(并且只有!)段,我们有一个完整的匹配。应用程序呈现BadUsersComponent
。回到最初的问题
OP使用以下路由器配置:
如果我们导航到根URL(
/
),路由器将如何解决:welcome
不匹配空段,因此跳过它。path: ''
匹配空段。它有一个pathMatch: 'full'
,这也是令人满意的,因为我们已经匹配了整个URL(它有一个空段)。1.重定向到
welcome
,应用程序呈现WelcomeComponent
。如果没有
pathMatch: 'full'
呢?实际上,人们会期望整个事情的表现完全相同。然而,Angular明确地阻止了这样的配置(
{ path: '', redirectTo: 'welcome' }
),因为如果你把这个**Route
放在welcome
上面,理论上会创建一个无休止的重定向循环。所以Angular只是抛出一个错误**,这就是为什么应用程序根本无法工作!(https://angular.io/api/router/Route#pathMatch)实际上,这对我来说没有太大的意义,因为Angular * 也 * 实现了对这种无休止的重定向的保护-它只在每个路由级别运行一个重定向!这将停止所有进一步的重定向(如您将在下面的示例中看到的)。
path: '**'
怎么样?path: '**'
将匹配绝对任何(af/frewf/321532152/fsa
是匹配),无论是否有pathMatch: 'full'
。此外,由于它匹配所有内容,因此还包括根路径,这使得**
{ path: '', redirectTo: 'welcome' }
**在此设置中完全冗余。有趣的是,拥有这样的配置是完全可以的:
如果我们导航到**
/welcome
,path: '**'
**将匹配,并将重定向到欢迎。从理论上讲,这应该会引发一个无休止的重定向循环,但Angular会立即停止这种循环(因为我前面提到的保护),整个过程都很好。p8h8hvxi2#
案例1
pathMatch:'full'
:在这种情况下,当应用程序在localhost:4200
(或某些服务器)上启动时,默认页面将是欢迎屏幕,因为url将是https://localhost:4200/
如果是
https://localhost:4200/gibberish
,则由于path:'**'
通配符,这将重定向到 pageNotFound 屏幕案例2
pathMatch:'prefix'
:如果路由有
{ path: '', redirectTo: 'welcome', pathMatch: 'prefix' }
,那么现在它将永远不会到达通配符路由,因为每个url都将匹配定义的path:''
。vqlkdk9b3#
当URL匹配的其余不匹配段是前缀路径时,
pathMatch = 'full'
会导致路由命中pathMatch = 'prefix'
告诉路由器在剩余URL以重定向路由的前缀路径开始时匹配重定向路由。参考:https://angular.io/guide/router#set-up-redirects
pathMatch: 'full'
意味着整个URL路径需要匹配,并且被路由匹配算法消耗。pathMatch: 'prefix'
表示选择了路径与URL开头匹配的第一条路由,但路由匹配算法会继续搜索与URL其余部分匹配的匹配子路由。lndjwyie4#
路径匹配策略,“prefix”或“full”之一。默认值为'prefix'。
默认情况下,路由器从左侧检查URL元素,以查看URL是否与给定路径匹配,并在匹配时停止。例如,'/team/11/user'匹配'team/:id'。
路径匹配策略“full”匹配整个URL。重定向空路径路由时,执行此操作非常重要。否则,由于空路径是任何URL的前缀,因此即使导航到重定向目的地,路由器也会应用重定向,从而创建无限循环。
来源:https://angular.io/api/router/Route#properties
t3psigkw5#
Angular的默认行为是:{pathMatch:'prefix'}。
现在,让我们看看两者之间的区别:
如果路径匹配:'prefix' => Angular将在routes数组中搜索路径(在URL中)的前缀。
如果路径匹配:'full' => Angular将在routes数组中搜索确切的路径(在URL中)。