Angularでは、「パスマッチ:フル」とは何ですか?どのような影響がありますか?


101

ここではフルパスマッチを使用しており、このパスマッチを削除すると、アプリのロードやプロジェクトの実行もできません

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 { }

回答:


110
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これがpageNotFound画面にリダイレクトされる場合path:'**'

ケース2 pathMatch:'prefix'

ルートにがある場合、 { path: '', redirectTo: 'welcome', pathMatch: 'prefix' }すべてのURLがpath:''定義されたものと一致するため、これはワイルドカードルートに到達しません。


こんにちは、この例を明確に説明していただきありがとうございますが、完全に明確にするために、別のタイプのルートを使用した別の例を挙げていただけますか?(子ルートなどの例を使用する場合など)。ありがとう
sohaieb

本当に素晴らしい説明ですが、内部レイアウトと外部レイアウトのように2つの異なるレイアウトで構成する方法を教えてください>
Kapil soni

87

pathMatch = 'full' URL一致の残りの一致しないセグメントがプレフィックスパスである場合、ルートヒットになります

pathMatch = 'prefix'残りのURL リダイレクトルートのプレフィックスパスで始まる場合、リダイレクトルートを照合するようにルーターに指示します。

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

pathMatch: 'full' つまり、URLパス全体が一致する必要があり、ルート一致アルゴリズムによって消費されます。

pathMatch: 'prefix' つまり、パスがURLの先頭と一致する最初のルートが選択されますが、その後、ルート一致アルゴリズムは、残りのURLが一致する一致する子ルートを検索し続けます。


24

技術的には正しいですが、他の答えは、AngularのURLからルートへのマッチングの説明から利益を得るでしょう。pathMatch: fullそもそもルーターがどのように機能するのかわからない場合、何をするかを完全に理解することはできないと思います。


まず、いくつかの基本的なことを定義しましょう。例として次のURLを使用します/users/james/articles?from=134#section

  1. 当たり前かもしれませんが、最初に、クエリパラメータ(?from=134)とフラグメント(#section)がパスマッチングに関与しないことを指摘しましょう。/users/james/articles重要なのはベースURL()だけです。

  2. AngularはURLをセグメントに分割します。のセグメント/users/james/articlesは、もちろんusersjamesarticlesです。

  3. ルーター構成は、単一のルートノードを持つツリー構造です。各Routeオブジェクトはノードであり、ノードを持つことができます。childrenノードは、他のノードを持つことも、childrenリーフノードになることもあります。

ルーターの目的は、ルートノードから始まるルーター構成ブランチを見つけることです。これは、URLのすべてのセグメント(!!!)正確に一致します。これは重要です!角度が一致する可能性があり、ルート構成ブランチ見つからない場合は全体の 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
  2. 'products' !== 'users'、その分岐をスキップします。.startsWith()or ではなく等価チェックを使用していることに注意してください.includes()-完全なセグメント一致のみがカウントされます!
  3. :other任意の値に一致するため、一致です。ただし、ターゲットURLはまだ完全に一致していないため(jamesandと一致する必要articlesがあります)、ルーターは子を探します。
    • の唯一の子:othertricksであり!== 'james'、なので、一致しません。
  4. その後、Angularはルート配列に戻り、そこから続行します。
  5. 'user' !== 'users、ブランチをスキップします。
  6. 'users' === 'users-セグメントが一致します。ただし、これはまだ完全一致ではないため、子を探す必要があります(ステップ3と同じ)。
    • 'permissions' !== 'james'、スキップします。
    • :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-セグメントがないないパス構成ので、一致usersとは、pathMatch: fullある完全なURLと一致しませんusers/james/articles
  2. 一致がないため、このブランチはスキップします。
  3. この時点で、一致するものが見つからずにルーター構成の最後に達しました。アプリケーションは何もレンダリングしません

例2

代わりにこれがあったらどうなるでしょう:

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

users/:userIDpathMatch: full試合だけusers/jamesので、それが再び無一致しませんし、アプリケーションが何もレンダリングしません。

例3

これを考えてみましょう:

{
  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全体)。それを行うことができないため、一致しません(したがって、このブランチはスキップします)。
  2. この場合も、URLに一致するものを見つけることができず、アプリケーションは何もレンダリングしません

お気づきかもしれませんが、pathMatch: full構成は基本的に次のように言っています。

私の子供を無視して、私だけに一致させます。残りのすべてのURLセグメントを自分で一致させることができない場合は、次に進みます。

リダイレクト

任意のRoute定義されているがredirectTo、同じ原理に基づいて、ターゲット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' -私たちは一致しています。
  3. このマッチにはがありredirectTo: 'not-found'すぐに適用されます。
  4. ターゲットURLがに変わりますnot-found
  5. ルーターは再度照合を開始し、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. usersURLの最初のセグメントと一致しますが、ルート構成はfull一致する必要があるため、スキップします。
  3. 'users/:userID'一致しusers/jamesます。articlesまだ一致していませんが、このルートには子があります。
    • 私たちarticlesは子供たちにマッチを見つけます。これでURL全体が照合され、アプリケーションがレンダリングされUserArticlesComponentます。

空のパス(path: ''

空のパスは、「消費」することなく任意のセグメントに一致する可能性があるため、少し特殊なケースです(そのため、子はそのセグメントに再度一致する必要があります)。この例を考えてみましょう:

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

アクセスしようとしているとしましょう/users

  • path: ''常に一致するため、ルートが一致します。ただし、URL全体が一致していません-まだ一致する必要がありusersます!
  • users残りの(そして唯一の!)セグメントと一致するchild があり、完全に一致していることがわかります。アプリケーションがレンダリングし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つの空のセグメントがありました)。
  3. リダイレクトがwelcome発生し、アプリケーションがレンダリングしWelcomeComponentます。

ない場合はどうなりpathMatch: 'full'ますか?

実際には、すべてがまったく同じように動作することが期待されます。ただし、Angularはこのような構成({ path: '', redirectTo: 'welcome' })を明示的に防止します。これをRoutewelcomeに置くと、理論的にはリダイレクトの無限ループが発生するためです。そのため、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はそれを即座に停止し、すべてが正常に機能します。


3

パスマッチング戦略。「プレフィックス」または「フル」のいずれか。デフォルトは 'prefix'です。

デフォルトでは、ルーターはURL要素を左からチェックして、URLが指定されたパスと一致するかどうかを確認し、一致する場合は停止します。たとえば、「/ team / 11 / user」は「team /:id」と一致します。

パス一致戦略「完全」は、URL全体に対して一致します。空のパスのルートをリダイレクトする場合、これを行うことが重要です。それ以外の場合は、空のパスが任意のURLのプレフィックスであるため、リダイレクト先に移動するときにもルーターがリダイレクトを適用し、無限ループが発生します。

ソース:https : //angular.io/api/router/Route#properties

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.