typescript 在Angular中,什么是'pathmatch:#21453;满,它有什么影响?

eoxn13cs  于 2023-06-07  发布在  TypeScript
关注(0)|答案(5)|浏览(141)

在这里,它是使用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 { }
yc0p9oo0

yc0p9oo01#

虽然在技术上是正确的,但其他答案将受益于Angular的URL到路由匹配的解释。如果你不知道路由器是如何工作的,我认为你不能完全(原谅这个双关语)理解**pathMatch: full的功能。
让我们首先定义一些基本的东西。我们将使用此URL作为示例:
/users/james/articles?from=134#section
1.这可能是显而易见的,但让我们首先指出
查询参数(?from=134)和片段(#section)在路径匹配中不起任何作用**。只有基本url(/users/james/articles)才重要。

  1. Angular将URL拆分为segments/users/james/articles的线段当然是usersjamesarticles
    1.路由器配置为具有单个根节点的 * 树 * 结构。每个**Route对象是一个节点,该节点可能有children节点,而这些节点又可能有其他children或者是叶子节点。
    路由器的目标是找到路由器配置 * 分支 *,从根节点开始,它将匹配
    所有(!!!)段的URL。”””这是至关重要的!*如果Angular没有找到匹配 * 整个 * URL的路由配置分支- * 不多不少 * -它将不会呈现 * 任何东西
    例如,如果您的目标URL是
    /a/b/c
    ,但路由器只能匹配**/a/b/a/b/c/d,则没有匹配项,应用程序将不会呈现任何内容。
    最后,带有
    redirectTo的路由与常规路由的行为 * 略有 * 不同,在我看来,它们是唯一一个任何人都想使用pathMatch: full**的地方。但我们稍后再谈这个。

默认(prefix)路径匹配

名称**prefix背后的原因是这样的路由配置将检查配置的path是否是剩余URL段的前缀。但是,路由器只能匹配全段**,这使得这个命名有点混乱。
无论如何,假设这是我们的根级路由器配置:

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对象都使用默认匹配策略,即prefix。此策略意味着路由器将遍历整个配置树,并尝试将其与目标URL进行匹配逐段**,直到URL***完全匹配***。下面是本例的实现方式:
1.迭代根数组,查找第一个URL段users的精确匹配。

  1. 'products' !== 'users',因此跳过该分支。请注意,我们使用的是相等性检查,而不是.startsWith().includes()-只有完整的段匹配计数!
  2. :other匹配任何值,所以它是匹配的。但是,目标URL尚未完全匹配(我们仍然需要匹配jamesarticles),因此路由器会查找子URL。
  • :other的唯一子代是tricks,也就是!== 'james',因此不匹配。

1.然后Angular返回到根数组并从那里继续。

  1. 'user' !== 'users,跳过分支。
  2. 'users' === 'users-段匹配。然而,这还不是完全匹配,因此我们需要查找子项(与步骤3相同)。
  • 'permissions' !== 'james',跳过它。
  1. :userID匹配任何东西,因此我们有james段的匹配。然而,这 * 仍然 * 不是完全匹配,因此我们需要寻找一个匹配articles的子节点。
    1.我们可以看到:userID有一个子路由articles,这给了我们一个完全匹配!因此,应用程序呈现UserArticlesComponent

匹配完整URL(full

示例1

现在假设**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,
        },
      ],
    },
  ],
}

注意**pathMatch: full**的用法。如果是这种情况,步骤1-5将是相同的,然而步骤6将是不同的:

  1. 'users' !== 'users/james/articles-段匹配,因为路径配置userspathMatch: full不匹配完整的URL,即users/james/articles
    1.由于没有匹配项,我们将跳过此分支。
    1.此时,我们到达了路由器配置的末尾,但没有找到匹配项。应用程序呈现 nothing

示例二

如果我们用这个来代替:

{
  path: 'users/:userID',
  component: UsersComponent,
  pathMatch: 'full',
  children: [
    {
      path: 'comments',
      component: UserCommentsComponent,
    },
    {
      path: 'articles',
      component: UserArticlesComponent,
    },
  ],
}

users/:userIDpathMatch: full只匹配users/james,因此它再次是不匹配的,并且应用程序不呈现任何内容。

示例三

让我们考虑一下:

{
  path: 'users',
  children: [
    {
      path: 'permissions',
      component: UsersPermissionsComponent,
    },
    {
      path: ':userID',
      component: UserComponent,
      pathMatch: 'full',
      children: [
        {
          path: 'comments',
          component: UserCommentsComponent,
        },
        {
          path: 'articles',
          component: UserArticlesComponent,
        },
      ],
    },
  ],
}

在这种情况下:

  1. 'users' === 'users-段匹配,但james/articles仍然不匹配。我们去找孩子吧。
  • 'permissions' !== 'james'-跳过。
  • :userID'只能匹配一个片段,即james。但是,它是一个pathMatch: full路由,并且它必须匹配james/articles(整个剩余的URL)。它不能做到这一点,因此它不是一个匹配(所以我们跳过这个分支)!

1.同样,我们没有找到任何匹配的URL,应用程序呈现 nothing
您可能已经注意到,pathMatch: full配置基本上是这样说的:
别理我的孩子,只配我。如果我自己无法匹配所有 * 剩余 * URL段,则继续前进。

重定向

任何定义了**redirectToRoute都会按照相同的原则匹配到目标URL。这里唯一的区别是 * 重定向会在匹配 * 时立即应用。这意味着如果重定向路由使用默认的prefix**策略,则 * 部分匹配足以导致重定向 *。这里有一个很好的例子:

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,
      },
    ],
  },
];

对于我们的初始URL(/users/james/articles),会发生以下情况:

  1. 'not-found' !== 'users'-跳过它。
  2. 'users' === 'users'-我们有一个匹配。
    1.这个匹配有一个redirectTo: 'not-found',它被 * 立即应用
    1.目标URL更改为not-found
    1.路由器再次开始匹配,并立即找到not-found的匹配项。应用程序呈现NotFoundComponent
    现在考虑如果
    *users路由也有pathMatch: full**会发生什么:
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,
      },
    ],
  },
];
  1. 'not-found' !== 'users'-跳过它。
  2. users将匹配URL的第一段,但路由配置要求full匹配,因此跳过它。
  3. 'users/:userID'匹配users/jamesarticles仍然不匹配,但此路由有子路由。
  • 我们在孩子身上找到了articles的匹配。现在匹配了整个URL,应用程序呈现UserArticlesComponent

空路径(path: ''

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

const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: 'users',
        component: BadUsersComponent,
      }
    ]
  },
  {
    path: 'users',
    component: GoodUsersComponent,
  },
];

假设我们正在尝试访问**/users**:

  • path: ''将始终匹配,因此路由匹配。但是,整个URL还没有匹配-我们仍然需要匹配users
  • 我们可以看到,有一个子users,它匹配剩余的(并且只有!)段,我们有一个完整的匹配。应用程序呈现BadUsersComponent

回到最初的问题

OP使用以下路由器配置:

const routes: Routes = [
  {
    path: 'welcome',
    component: WelcomeComponent,
  },
  {
    path: '',
    redirectTo: 'welcome',
    pathMatch: 'full',
  },
  {
    path: '**',
    redirectTo: 'welcome',
    pathMatch: 'full',
  },
];

如果我们导航到根URL(/),路由器将如何解决:

  1. welcome不匹配空段,因此跳过它。
  2. 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' }**在此设置中完全冗余。
有趣的是,拥有这样的配置是完全可以的:

const routes: Routes = [
  {
    path: '**',
    redirectTo: 'welcome'
  },
  {
    path: 'welcome',
    component: WelcomeComponent,
  },
];

如果我们导航到**/welcomepath: '**'**将匹配,并将重定向到欢迎。从理论上讲,这应该会引发一个无休止的重定向循环,但Angular会立即停止这种循环(因为我前面提到的保护),整个过程都很好。

p8h8hvxi

p8h8hvxi2#

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

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

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

案例2pathMatch:'prefix'

如果路由有{ path: '', redirectTo: 'welcome', pathMatch: 'prefix' },那么现在它将永远不会到达通配符路由,因为每个url都将匹配定义的path:''

vqlkdk9b

vqlkdk9b3#

当URL匹配的其余不匹配段是前缀路径时,pathMatch = 'full'会导致路由命中
pathMatch = 'prefix'告诉路由器在剩余URL以重定向路由的前缀路径开始时匹配重定向路由。
参考:https://angular.io/guide/router#set-up-redirects
pathMatch: 'full'意味着整个URL路径需要匹配,并且被路由匹配算法消耗。
pathMatch: 'prefix'表示选择了路径与URL开头匹配的第一条路由,但路由匹配算法会继续搜索与URL其余部分匹配的匹配子路由。

lndjwyie

lndjwyie4#

路径匹配策略,“prefix”或“full”之一。默认值为'prefix'。
默认情况下,路由器从左侧检查URL元素,以查看URL是否与给定路径匹配,并在匹配时停止。例如,'/team/11/user'匹配'team/:id'。
路径匹配策略“full”匹配整个URL。重定向空路径路由时,执行此操作非常重要。否则,由于空路径是任何URL的前缀,因此即使导航到重定向目的地,路由器也会应用重定向,从而创建无限循环。
来源:https://angular.io/api/router/Route#properties

t3psigkw

t3psigkw5#

Angular的默认行为是:{pathMatch:'prefix'}。
现在,让我们看看两者之间的区别:
如果路径匹配:'prefix' => Angular将在routes数组中搜索路径(在URL中)的前缀。
如果路径匹配:'full' => Angular将在routes数组中搜索确切的路径(在URL中)。

相关问题