技術的には正しいですが、他の答えは、AngularのURLからルートへのマッチングの説明から利益を得るでしょう。pathMatch: fullそもそもルーターがどのように機能するのかわからない場合、何をするかを完全に理解することはできないと思います。
まず、いくつかの基本的なことを定義しましょう。例として次のURLを使用します/users/james/articles?from=134#section。
当たり前かもしれませんが、最初に、クエリパラメータ(?from=134)とフラグメント(#section)がパスマッチングに関与しないことを指摘しましょう。/users/james/articles重要なのはベースURL()だけです。
AngularはURLをセグメントに分割します。のセグメント/users/james/articlesは、もちろんusers、jamesとarticlesです。
ルーター構成は、単一のルートノードを持つツリー構造です。各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と照合しようとすることを意味します。この例の場合、次のようになります。
- ルート配列を反復処理して、最初のURLセグメントの完全一致を探します-
users。
'products' !== 'users'、その分岐をスキップします。.startsWith()or ではなく等価チェックを使用していることに注意してください.includes()-完全なセグメント一致のみがカウントされます!
:other任意の値に一致するため、一致です。ただし、ターゲットURLはまだ完全に一致していないため(jamesandと一致する必要articlesがあります)、ルーターは子を探します。
- の唯一の子
:otherはtricksであり!== 'james'、なので、一致しません。
- その後、Angularはルート配列に戻り、そこから続行します。
'user' !== 'users、ブランチをスキップします。
'users' === 'users-セグメントが一致します。ただし、これはまだ完全一致ではないため、子を探す必要があります(ステップ3と同じ)。
'permissions' !== 'james'、スキップします。
:userIDすべてに一致するため、jamesセグメントに一致します。ただし、これはまだ完全一致ではないため、に一致する子を探す必要がありますarticles。
- これには
: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は異なります。
'users' !== 'users/james/articles-セグメントがないないパス構成ので、一致usersとは、pathMatch: fullある完全なURLと一致しませんusers/james/articles。
- 一致がないため、このブランチはスキップします。
- この時点で、一致するものが見つからずにルーター構成の最後に達しました。アプリケーションは何もレンダリングしません。
例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,
},
],
},
],
}
この場合:
'users' === 'users-セグメントは一致していますが、james/articlesまだ一致していません。子供を探しましょう。
'permissions' !== 'james' -スキップ。
:userID'は単一のセグメントにのみ一致できますjames。ただし、これはpathMatch: fullルートであり、一致する必要がありjames/articlesます(残りのURL全体)。それを行うことができないため、一致しません(したがって、このブランチはスキップします)。
- この場合も、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)では、次のようになります。
'not-found' !== 'users' -スキップしてください。
'users' === 'users' -私たちは一致しています。
- このマッチにはがあり
redirectTo: 'not-found'、すぐに適用されます。
- ターゲットURLがに変わります
not-found。
- ルーターは再度照合を開始し、
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,
},
],
},
];
'not-found' !== 'users' -スキップしてください。
usersURLの最初のセグメントと一致しますが、ルート構成はfull一致する必要があるため、スキップします。
'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(/)に移動している場合、ルーターがそれを解決する方法は次のとおりです。
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' }ため、このセットアップでは冗長になります。
おかしなことに、この構成にするのはまったく問題ありません。
const routes: Routes = [
{
path: '**',
redirectTo: 'welcome'
},
{
path: 'welcome',
component: WelcomeComponent,
},
];
我々はに移動した場合は/welcome、path: '**'試合になると歓迎へのリダイレクトが発生します。これによりリダイレクトの無限ループが開始されますが、Angularはそれを即座に停止し、すべてが正常に機能します。