149 votes

Dans Angular, qu'est-ce que "pathmatch : full" et quel est son effet ?

Ici, le pathmatch est utilisé comme complet et lorsque je supprime ce pathmatch, l'application n'est même pas chargée et le projet n'est pas exécuté.

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

142voto

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

Cas 1 pathMatch:'full' : Dans ce cas, lorsque l'application est lancée sur localhost:4200 (ou un autre serveur), la page par défaut sera l'écran de bienvenue, puisque l'url sera https://localhost:4200/

Si https://localhost:4200/gibberish cela redirigera vers pageNotFound écran en raison de path:'**' joker

Cas 2 pathMatch:'prefix' :

Si les routes ont { path: '', redirectTo: 'welcome', pathMatch: 'prefix' } Maintenant, cela n'atteindra jamais la route joker puisque toutes les url correspondront. path:'' défini.

0 votes

Bonjour, merci pour l'explication claire de cet exemple, mais pouvez-vous donner un autre exemple avec un autre type de routes pour le rendre complètement clair ? (comme utiliser un exemple avec des routes pour enfants, etc. ). merci

0 votes

Vraiment bien expliqué monsieur mais pouvez-vous me dire comment configurer avec 2 mises en page différentes, comme la mise en page intérieure et la mise en page extérieure ?

0 votes

Je ne peux pas reproduire le Case 2 . Voici un exemple où je m'attendais à ce que la première route corresponde à tout, mais ce n'est pas le cas. J'ai demandé cette question pour essayer d'avoir une explication

112voto

Avius Points 327

Bien que techniquement correctes, les autres réponses bénéficieraient d'une explication de la correspondance URL/route d'Angular. Je ne pense pas que vous puissiez comprendre pleinement (pardonnez le jeu de mots) ce qu'est la correspondance URL-route d'Angular. pathMatch: full si vous ne savez pas comment fonctionne le routeur.


Définissons d'abord quelques éléments de base. Nous allons utiliser cette URL comme exemple : /users/james/articles?from=134#section .

  1. C'est peut-être évident, mais soulignons d'abord que paramètres d'interrogation ( ?from=134 ) et des fragments ( #section ) ne jouent aucun rôle dans la correspondance des chemins . Seule l'url de base ( /users/james/articles ) est important.

  2. Angular divise les URLs en segments . Les segments de /users/james/articles sont, bien sûr, users , james y articles .

  3. La configuration du routeur est un arbre avec un seul nœud racine. Chaque Route est un nœud, qui peut avoir children qui peuvent à leur tour avoir d'autres children ou être des nœuds feuilles.

Le but du routeur est de trouver une configuration de routeur branche en commençant par le nœud racine, ce qui correspondrait à exactement tout ( !!!) des segments de l'URL. C'est crucial ! Si Angular ne trouve pas de branche de configuration de route qui pourrait correspondre à l'élément ensemble du site URL - ni plus ni moins - il ne rendra pas tout ce qui est .

Par exemple, si votre URL cible est /a/b/c mais le routeur ne peut correspondre qu'à l'un ou l'autre des éléments suivants /a/b o /a/b/c/d alors il n'y a pas de correspondance et l'application ne rendra rien.

Enfin, les routes avec redirectTo se comporter légèrement différemment des routes régulières, et il me semble que ce serait le seul endroit où quelqu'un voudrait vraiment utiliser pathMatch: full . Mais nous y reviendrons plus tard.

Par défaut ( prefix ) correspondance des chemins

La raison d'être du nom prefix c'est qu'une telle configuration de route vérifiera si la route configurée path est un préfixe des segments d'URL restants. Cependant, le routeur est seulement capable de faire correspondre segments complets ce qui rend cette dénomination légèrement confuse.

Quoi qu'il en soit, disons qu'il s'agit de notre configuration de routeur au niveau de la racine :

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

Notez que chaque Route utilise ici la stratégie de correspondance par défaut, qui est prefix . Cette stratégie signifie que le routeur itère sur l'ensemble de l'arbre de configuration et essaie de le faire correspondre à l'URL cible. segment par segment jusqu'à ce que l'URL soit parfaitement adaptés . Voici comment procéder pour cet exemple :

  1. Itérer sur le tableau Root à la recherche d'une correspondance exacte pour le premier segment d'URL. users .
  2. 'products' !== 'users' alors sautez cette branche. Notez que nous utilisons une vérification de l'égalité plutôt qu'une vérification de l'existence d'une .startsWith() o .includes() - seuls les matches à segment complet comptent !
  3. :other correspond à n'importe quelle valeur, donc c'est une correspondance. Cependant, l'URL cible n'a pas encore été entièrement trouvée (nous devons encore trouver une correspondance avec la valeur james y articles ), le routeur recherche donc les enfants.
  • L'unique enfant de :other es tricks que es !== 'james' donc pas de correspondance.
  1. Angular revient ensuite au tableau Root et continue à partir de là.
  2. 'user' !== 'users , sauter la branche.
  3. 'users' === 'users - le segment correspond. Cependant, il ne s'agit pas encore d'une correspondance complète, nous devons donc rechercher les enfants (comme à l'étape 3).
  • 'permissions' !== 'james' passez votre chemin.
  • :userID correspond à n'importe quoi, donc nous avons une correspondance pour l'élément james segment. Toutefois, il s'agit toujours pas une correspondance complète, donc nous devons chercher un enfant qui correspondrait à articles .
    1. On peut voir que :userID a une route enfant articles ce qui nous donne une correspondance complète ! Ainsi l'application rend UserArticlesComponent .

URL complet ( full ) correspondant

Exemple 1

Imaginez maintenant que le users L'objet de configuration de la route ressemblait à ceci :

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

Notez l'utilisation de pathMatch: full . Si c'était le cas, les étapes 1 à 5 seraient les mêmes, mais l'étape 6 serait différente :

  1. 'users' !== 'users/james/articles - le segment fait no correspondent parce que la configuration du chemin users avec pathMatch: full ne correspond pas à l'URL complète, qui est users/james/articles .
  2. Comme il n'y a pas de correspondance, nous sautons cette branche.
  3. À ce stade, nous avons atteint la fin de la configuration du routeur sans avoir trouvé de correspondance. L'application rend rien .

Exemple 2

Et si on avait ça à la place :

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

users/:userID avec pathMatch: full ne correspond qu'à users/james Il n'y a donc pas de correspondance, une fois de plus, et l'application ne rend rien.

Exemple 3

Considérons ceci :

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

Dans ce cas :

  1. 'users' === 'users - le segment correspond, mais james/articles reste toujours inégalée. Cherchons des enfants.
  • 'permissions' !== 'james' - sauter.
  • :userID' ne peut correspondre qu'à un seul segment, ce qui serait james . Cependant, c'est un pathMatch: full et il doit correspondre à james/articles (toute l'URL restante). Il n'est pas capable de faire cela et donc ce n'est pas une correspondance (donc nous sautons cette branche) !
  1. Encore une fois, nous n'avons pas réussi à trouver de correspondance pour l'URL et l'application rendra rien .

Comme vous l'avez peut-être remarqué, un pathMatch: full

Ignorez mes enfants et n'affrontez que moi. Si je ne suis pas en mesure de correspondre à tous les restant Je me segmente en URL, puis je passe à autre chose.

Redirections

Tout Route qui a défini un redirectTo seront comparés à l'URL cible selon les mêmes principes. La seule différence ici est que la redirection est appliquée dès qu'un segment correspond à . Cela signifie que si une route de redirection utilise l'adresse par défaut de l'utilisateur. prefix stratégie, une une correspondance partielle est suffisante pour provoquer une redirection . Voici un bon exemple :

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

Pour notre URL initiale ( /users/james/articles ), voici ce qui se passerait :

  1. 'not-found' !== 'users' - sautez-la.
  2. 'users' === 'users' - nous avons une correspondance.
  3. Ce match a un redirectTo: 'not-found' que es appliqué immédiatement .
  4. L'URL cible devient not-found .
  5. Le routeur recommence à chercher des correspondances et trouve une correspondance pour not-found tout de suite. L'application rend NotFoundComponent .

Maintenant, considérez ce qui se passerait si le users La route avait également 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' - sautez-la.
  2. users correspondrait au premier segment de l'URL, mais la configuration de l'itinéraire exige un full correspond, donc passez-le.
  3. 'users/:userID' correspond à users/james . articles ne correspond toujours pas mais cette route a des enfants.
  • Nous trouvons une correspondance pour articles dans les enfants. L'ensemble de l'URL est maintenant apparié et l'application effectue le rendu suivant UserArticlesComponent .

Chemin vide ( path: '' )

Le chemin vide est un cas un peu particulier car il peut correspondre à cualquier segment sans le "consommer" (de sorte que ses enfants devraient à nouveau correspondre à ce segment). Prenons cet exemple :

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

Disons que nous essayons d'accéder /users :

  • path: '' correspondra toujours, donc la route correspondra. Cependant, la totalité de l'URL n'a pas été trouvée - nous devons encore trouver une correspondance avec les éléments suivants users !
  • Nous pouvons voir qu'il y a un enfant users qui correspond au segment restant (et le seul !) et nous avons une correspondance complète. L'application rend BadUsersComponent .

Revenons maintenant à la question initiale

L'OP a utilisé cette configuration de routeur :

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

Si nous naviguons vers l'URL racine ( / ), voici comment le routeur va résoudre ce problème :

  1. welcome ne correspond pas à un segment vide, il est donc ignoré.
  2. path: '' correspond au segment vide. Il a un pathMatch: 'full' ce qui est également satisfaisant car nous avons fait correspondre l'URL entière (elle avait un seul segment vide).
  3. Une redirection vers welcome se produit et l'application rend WelcomeComponent .

Et s'il n'y avait pas pathMatch: 'full' ?

En fait, on s'attendrait à ce que l'ensemble se comporte exactement de la même manière. Cependant, Angular empêche explicitement une telle configuration ( { path: '', redirectTo: 'welcome' } ) parce que si vous mettez ce Route au-dessus de welcome cela créerait théoriquement une boucle sans fin de redirections. Donc Angular a juste lance une erreur C'est pourquoi l'application ne fonctionne pas du tout ! ( https://angular.io/api/router/Route#pathMatch )

En fait, cela n'a pas beaucoup de sens pour moi car Angular également a mis en place une protection contre ces redirections sans fin : il n'exécute qu'une seule redirection par niveau de routage ! Cela permet d'arrêter toutes les autres redirections (comme vous le verrez dans l'exemple ci-dessous).

Qu'en est-il path: '**' ?

`path: ''** correspondra à **absolument tout** ( **af/frewf/321532152/fsa** est une correspondance) avec ou sans un **pathMatch: 'full'`** .

De plus, comme il correspond à tout, le chemin de la racine est également inclus, ce qui fait que { path: '', redirectTo: 'welcome' } complètement redondant dans cette configuration.

Il est amusant de constater que cette configuration est parfaitement acceptable :

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

Si nous naviguons vers /welcome , `path: ''`** correspondra et une redirection vers l'accueil se produira. Théoriquement, cela devrait déclencher une boucle sans fin de redirections, mais Angular l'arrête immédiatement (grâce à la protection que j'ai mentionnée précédemment) et l'ensemble fonctionne parfaitement.

0 votes

Pour mémoire, c'est moi qui suis à l'origine de la ignore my children explication moi-même. Je doute que ce soit la façon dont les développeurs Angular voient les choses, mais c'est le cas. est l'un des principes de la pathMatch: 'full' . Ainsi, dans l'exemple de redirection auquel vous faites référence, vous remarquerez que pathMath: 'full' est appliquée à la deuxième route ( path: 'users' ), qui, de ce fait, ne no match. L'itinéraire correspondant est path: 'users/:userID' qui n'utilise pas de pathMatch: 'full' et fonctionne comme d'habitude. Il y a donc d'abord correspondance users/james puis nous recherchons articles dans ses enfants (une fois de plus, il n'utilise pas de pathMatch: 'full' ).

0 votes

Je me suis un peu perdue dans les What if there was no pathMatch: 'full'? section. Pourquoi cela créerait une boucle sans fin si / correspondances { path: '', redirectTo: 'welcome' } et redirige vers welcome et modifie l'URL en welcome en même temps ? Pourquoi le rendu de WelcomeComponent ne se fait-il pas ?

0 votes

Vous devriez peut-être relire tout ce qui a été dit à partir de l'article Chemin vide ( path: '' ) section. Un chemin vide ( path: '' ) correspondra à n'importe quel segment Ainsi, non seulement / mais aussi /welcome . Cela signifie qu'une fois que l'URL est passée de / a /welcome , path: '' sera encore une fois au rendez-vous : ] c'est un peu bizarre, non ? C'est un cas spécial dans le système de routage. Je ne sais pas pourquoi il a été conçu ainsi (je n'y ai jamais vraiment réfléchi, mais cela permet probablement d'avoir des arbres de composants pratiques), mais c'est exactement la raison pour laquelle il faut utiliser pathMatch: 'full' - il oblige path: '' pour correspondre exactement / !

102voto

Pardeep Jain Points 4603

pathMatch = 'full' donne un résultat positif lorsque les segments restants non appariés de l'URL correspondent au chemin du préfixe.

pathMatch = 'prefix' indique au routeur de correspondre à la route de redirection lorsque l'URL restante commence avec le chemin du préfixe de la route de redirection.

Réf : https://angular.io/guide/router#set-up-redirects

pathMatch: 'full' signifie que l'ensemble du chemin URL doit correspondre et est consommé par l'algorithme de mise en correspondance des routes.

pathMatch: 'prefix' En d'autres termes, la première route dont le chemin correspond au début de l'URL est choisie, mais l'algorithme de mise en correspondance des routes continue ensuite à rechercher des routes enfant correspondantes pour le reste de l'URL.

7voto

Ayoub Ghozzi Points 65

La stratégie de correspondance des chemins, entre "préfixe" et "complet". La valeur par défaut est "prefix".

Par défaut, le routeur vérifie les éléments d'URL à partir de la gauche pour voir si l'URL correspond à un chemin d'accès donné, et s'arrête lorsqu'il y a une correspondance. Par exemple, '/team/11/user' correspond à 'team/:id'.

La stratégie de recherche par chemin d'accès "complète" permet de rechercher l'intégralité de l'URL. Il est important de procéder ainsi lors de la redirection de routes à chemin vide. Sinon, comme un chemin vide est un préfixe de n'importe quelle URL, le routeur appliquerait la redirection même lors de la navigation vers la destination de la redirection, créant ainsi une boucle sans fin.

Source : https://angular.io/api/router/Route#properties

1 votes

Cette explication (parmi celles données) est, à mon avis, la plus simple et la plus facile à comprendre.

0voto

Vishal Sharma Points 1

Le comportement par défaut d'Angular est le suivant : {pathMatch : 'prefix'} pour toutes les routes.

Voyons maintenant quelle est la différence entre les deux :

Si pathMatch : 'prefix' => Angular recherchera un préfixe du chemin (dans l'URL) dans le tableau des routes.

Si pathMatch : 'full' => Angular recherchera le chemin exact (dans l'URL) dans le tableau des routes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X