在Angular中,什么是&path;匹配:full'它有什么影响?

时间:2017-03-24 05:43:24

标签: angular typescript

在这里,它使用pathmatch为full,当我删除这个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 { }

4 个答案:

答案 0 :(得分:53)

  

pathMatch ='完整'当URL匹配的其余不匹配段是前缀路径

时,会导致路由命中      

pathMatch ='前缀'当剩余的URL 开始时,告诉路由器匹配重定向路由与重定向路由的前缀路径。

参考:https://angular.io/guide/router#set-up-redirects

pathMatch: 'full'表示整个URL路径需要匹配并由路由匹配算法使用。

pathMatch: 'prefix'表示选择了路径与URL开头匹配的第一条路由,但是路由匹配算法正在继续搜索其余URL匹配的匹配子路由。

答案 1 :(得分:40)

虽然技术上正确,但其他答案将从对Angular的URL到路由匹配的解释中受益。如果您一开始不知道路由器的工作原理,我想您不能完全理解 pathMatch: full


让我们首先定义一些基本的东西。我们以以下URL为例: /users/james/articles?from=134#section

  1. 这很明显,但我们首先要指出查询参数(?from=134)和片段(#section)在路径匹配中不起作用。仅基本网址( /users/james/articles )。

  2. Angular将URL分成。当然, /users/james/articles 的细分是 users james { {1}}

  3. 路由器配置是具有单个根节点的 tree 结构。每个 articles 对象都是一个节点,该节点可能具有 Route 节点,而这些节点又可能具有其他 children < / strong>,也可以是叶节点。

路由器的目标是从根节点开始查找路由器配置分支,该配置将与网址的完全(!!!)段匹配。 这至关重要!!如果Angular找不到与 整个 URL匹配的路由配置分支- 至少 -它不会呈现 任何内容

例如如果您的目标URL是 children ,但路由器只能匹配 /a/b/c /a/b >,则没有匹配项,应用程序将不会呈现任何内容。

最后,带有 /a/b/c/d 的路线与常规路线的行为略有不同,在我看来,它们将是唯一一个真正有人可以到达的地方想要使用 redirectTo 。但是我们稍后再讨论。

默认(pathMatch: full)路径匹配

名称 prefix 的原因是,这样的路由配置将检查配置的 prefix 是否为其余URL的前缀段。但是,路由器只能匹配全段,这使命名有些混乱。

无论如何,这是我们的根级路由器配置:

path

请注意,此处的每个 const routes: Routes = [ { path: 'products', children: [ { path: ':productID', component: ProductComponent, }, ], }, { path: ':other', children: [ { path: 'tricks', component: TricksComponent, }, ], }, { path: 'user', component: UsersonComponent, }, { path: 'users', children: [ { path: 'permissions', component: UsersPermissionsComponent, }, { path: ':userID', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ], }, ]; 对象都使用默认的匹配策略,即 Route 。此策略意味着路由器会遍历整个配置树,并尝试将其与目标URL 按段分段 进行匹配,直到URL 完全匹配 。对于此示例,将执行以下操作:

  1. 遍历根数组,查找与第一个URL段-prefix完全匹配的内容。
  2. users,所以跳过该分支。请注意,我们使用的是相等性检查,而不是'products' !== 'users'.startsWith()-只有完整的句段匹配计数!
  3. .includes()匹配任何值,因此是匹配项。但是,目标URL尚未完全匹配(我们仍然需要匹配:otherjames),因此路由器会寻找子代。
  • articles的唯一子项是:other,即tricks,因此不是匹配项。
  1. Angular然后回溯到根数组并从那里继续。
  2. !== 'james',跳过分支。
  3. 'user' !== 'users-段匹配。但是,这还不是完全匹配,因此我们需要寻找孩子(与第3步相同)。
  • 'users' === 'users,跳过它。
  • 'permissions' !== 'james'匹配任何内容,因此我们有:userID段的匹配项。但是,这仍然不是完全匹配,因此我们需要寻找一个匹配james的孩子。
    1. 我们可以看到articles拥有一条子路线:userID,这给了我们完整的比赛机会!因此,应用程序呈现了articles

完整的URL(UserArticlesComponent)匹配

示例1

现在想象一下 full 路由配置对象如下:

users

请注意 { path: 'users', component: UsersComponent, pathMatch: 'full', children: [ { path: 'permissions', component: UsersPermissionsComponent, }, { path: ':userID', component: UserComponent, children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ], } 的用法。如果是这种情况,步骤1-5将相同,但是步骤6将有所不同:

  1. pathMatch: full-该段不匹配,因为路径配置'users' !== 'users/james/articlesusers与完整的URL(pathMatch: full)不匹配。
  2. 由于没有匹配项,我们将跳过此分支。
  3. 这时,我们到达路由器配置的末尾,但没有找到匹配项。该应用程序不显示任何内容。

示例2

如果我们改用这个怎么办?

users/james/articles

{ path: 'users/:userID', component: UsersComponent, pathMatch: 'full', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], } users/:userID仅匹配pathMatch: full,因此再次不匹配,并且应用程序不呈现任何内容。

示例3

让我们考虑一下:

users/james

在这种情况下:

  1. { path: 'users', children: [ { path: 'permissions', component: UsersPermissionsComponent, }, { path: ':userID', component: UserComponent, pathMatch: 'full', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ], } -段匹配,但是'users' === 'users仍然不匹配。让我们找孩子。
  • james/articles-跳过。
  • 'permissions' !== 'james'只能匹配一个段,即:userID'。但是,这是一条james路由,它必须与pathMatch: full(整个剩余URL)匹配。它无法做到这一点,因此不是匹配项(因此我们跳过此分支)!
  1. 同样,我们找不到与URL匹配的任何内容,并且应用程序未显示任何内容。

您可能已经注意到,james/articles配置基本上是这样说的:

忽略我的孩子,只匹配我。如果我自己无法匹配所有剩余的 URL片段,请继续。

重定向

任何已定义 pathMatch: full Route 都将根据相同的原则与目标URL进行匹配。唯一的区别是,匹配后,就会立即应用重定向。这意味着,如果重定向路由使用默认的 redirectTo 策略,则部分匹配足以引起重定向。这是一个很好的例子:

prefix

对于我们的初始URL( const routes: Routes = [ { path: 'not-found', component: NotFoundComponent, }, { path: 'users', redirectTo: 'not-found', }, { path: 'users/:userID', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ]; ),将发生以下情况:

  1. /users/james/articles-跳过它。
  2. 'not-found' !== 'users'-我们有一场比赛。
  3. 此比赛有一个'users' === 'users',它立即应用
  4. 目标URL更改为redirectTo: 'not-found'
  5. 路由器再次开始匹配,并立即找到not-found的匹配项。该应用程序呈现not-found

现在考虑如果 NotFoundComponent 路线也具有 users 会发生什么情况:

pathMatch: full
  1. const routes: Routes = [ { path: 'not-found', component: NotFoundComponent, }, { path: 'users', pathMatch: 'full', redirectTo: 'not-found', }, { path: 'users/:userID', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ]; -跳过它。
  2. 'not-found' !== 'users'将匹配URL的第一段,但是路由配置需要users匹配,因此将其跳过。
  3. full'users/:userID'相匹配。 users/james仍不匹配,但此路线有子级。
  • 我们在孩子中找到了articles的匹配项。现在,整个URL都已匹配,并且应用程序呈现articles

空路径(UserArticlesComponent

空路径有点特殊,因为它可以匹配任何 而无需“消耗”它(因此,子级必须再次匹配该段) 。考虑以下示例:

path: ''

假设我们正在尝试访问 const routes: Routes = [ { path: '', children: [ { path: 'users', component: BadUsersComponent, } ] }, { path: 'users', component: GoodUsersComponent, }, ];

  • /users将始终匹配,因此路由匹配。但是,整个URL尚未匹配-我们仍然需要匹配path: ''
  • 我们可以看到有一个子users,它与其余(且唯一!)段匹配,并且我们有一个完全匹配项。该应用程序呈现users

现在回到原始问题

OP使用了以下路由器配置:

BadUsersComponent

如果我们导航到根URL( const routes: Routes = [ { path: 'welcome', component: WelcomeComponent, }, { path: '', redirectTo: 'welcome', pathMatch: 'full', }, { path: '**', redirectTo: 'welcome', pathMatch: 'full', }, ]; ),则路由器将解决以下问题:

  1. /与空白句段不匹配,请跳过它。
  2. welcome与空白句段匹配。它有一个path: '',因为我们已经匹配了整个URL(它有一个空段),所以也很满意。
  3. 发生到pathMatch: 'full'的重定向,应用程序呈现welcome

如果没有WelcomeComponent怎么办?

实际上,人们会期望整个事情的行为完全相同。但是,Angular明确禁止这种配置( pathMatch: 'full' ),因为如果将 { path: '', redirectTo: 'welcome' } 放在Route上方,理论上会创建无限循环的重定向。因此Angular只会引发错误,这就是为什么该应用程序根本无法运行的原因! (https://angular.io/api/router/Route#pathMatch

实际上,这对我来说并没有太大意义,因为Angular 还实现了针对此类无穷重定向的保护-它仅在每个路由级别运行一次重定向!这将停止所有进一步的重定向(如下面的示例所示)。

welcome呢?

path: '**' 将与绝对任何匹配( path: '**' 是匹配项),带有或不带有 af/frewf/321532152/fsa

此外,由于它匹配所有内容,因此还包含了根路径,这使得 pathMatch: 'full' 在此设置中完全多余。

有趣的是,具有此配置是完全可以的:

{ path: '', redirectTo: 'welcome' }

如果我们导航到 const routes: Routes = [ { path: '**', redirectTo: 'welcome' }, { path: 'welcome', component: WelcomeComponent, }, ]; /welcome 将是一个匹配项,并且将重定向到“欢迎”。从理论上讲,这应该会引发一个无限循环的重定向,但是Angular会立即停止该重定向(由于我前面提到的保护),并且整个过程都很好。

答案 2 :(得分:28)

RouterModule.forRoot([
      { path: 'welcome', component: WelcomeComponent },
      { path: '', redirectTo: 'welcome', pathMatch: 'full' },
      { path: '**', component: 'pageNotFoundComponent' }
    ])

案例1 pathMatch:'full': 在这种情况下,在localhost:4200(或某些服务器)上启动应用程序时,默认页面将为欢迎屏幕,因为URL为https://localhost:4200/

如果https://localhost:4200/gibberish由于path:'**'通配符而将重定向到 pageNotFound 屏幕

案例2  pathMatch:'prefix'

如果路由中有{ path: '', redirectTo: 'welcome', pathMatch: 'prefix' },则此路由将永远不会到达通配符路由,因为每个网址都将与定义的path:''相匹配。

答案 3 :(得分:3)

路径匹配策略,“ prefix”或“ full”之一。默认值为“前缀”。

默认情况下,路由器从左侧检查URL元素以查看URL是否与给定路径匹配,并在匹配时停止。例如,“ / team / 11 / user”与“ team /:id”匹配。

路径匹配策略“完整”与整个URL匹配。重定向空路径路由时,执行此操作很重要。否则,因为空路径是任何URL的前缀,所以路由器即使在导航到重定向目标时也会应用重定向,从而造成无限循环。

来源:https://angular.io/api/router/Route#properties