Dans Angular, qu'est-ce que «pathmatch: full» et quel effet a-t-il?

101

Ici, il utilise pathmatch comme complet et lorsque je supprime ce pathmatch, il ne charge même pas l'application ou n'exécute pas le projet

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 { }
GCJAmarasinghe
la source

Réponses:

110
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 sur un serveur), la page par défaut sera l'écran de bienvenue, car l'url serahttps://localhost:4200/

Si https://localhost:4200/gibberishcela redirige vers l' écran pageNotFound en raison d'un path:'**'caractère générique

Cas 2 pathMatch:'prefix' :

Si les routes ont { path: '', redirectTo: 'welcome', pathMatch: 'prefix' }, maintenant cela n'atteindra jamais la route générique puisque chaque URL correspondrait à celle path:''définie.

sai amar
la source
bonjour, merci pour l'explication claire de cet exemple, mais pouvez-vous donner un autre exemple avec un autre type d'itinéraires pour le rendre complètement clair s'il vous plaît? (comme en utilisant un exemple avec des routes enfants etc.). merci
sohaieb le
très belle explication monsieur mais pouvez-vous me dire comment configurer avec 2 agencements différents, comme l'agencement intérieur et l'agencement extérieur>
Kapil soni
87

pathMatch = 'full' entraîne un accès d'itinéraire lorsque les segments restants non correspondants de l'URL correspondent au chemin du préfixe

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

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

pathMatch: 'full' signifie que tout le chemin de l'URL doit correspondre et est consommé par l'algorithme de correspondance d'itinéraire.

pathMatch: 'prefix' signifie que la première route où le chemin correspond au début de l'URL est choisie, mais alors l'algorithme de correspondance d'itinéraire continue à rechercher des routes enfants correspondantes là où le reste de l'URL correspond.

Pardeep Jain
la source
24

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 pleinement (pardonnez le jeu de mots) comprendre ce qui se pathMatch: fullpasse si vous ne savez pas comment le routeur fonctionne en premier lieu.


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

  1. Cela peut être évident, mais soulignons d'abord que les paramètres de requête ( ?from=134) et fragments ( #section) ne jouent aucun rôle dans la correspondance de chemin . Seule l'url de base ( /users/james/articles) compte.

  2. Angular divise les URL en segments . Les segments de /users/james/articlessont, bien sûr users, jameset articles.

  3. La configuration du routeur est une arborescence avec un seul nœud racine. Chaque Routeobjet est un nœud, qui peut avoir des childrennœuds, qui peuvent à leur tour en avoir d'autres childrenou être des nœuds feuilles.

Le but du routeur est de trouver une branche de configuration du routeur , en commençant par le nœud racine, qui correspondrait exactement à tous les segments (!!!) de l'URL. C'est crucial! Si Angular ne trouve pas de branche de configuration d'itinéraire qui pourrait correspondre à l' URL entière - ni plus ni moins - il ne rendra rien .

Par exemple, si votre URL cible est /a/b/cmais que le routeur ne peut correspondre qu'à l'un /a/bou l' autre /a/b/c/d, alors il n'y a pas de correspondance et l'application ne rendra rien.

Enfin, les itinéraires avec redirectTose comportent légèrement différemment des itinéraires réguliers, et il me semble qu'ils seraient le seul endroit où quiconque voudrait vraiment utiliserpathMatch: full . Mais nous y reviendrons plus tard.

prefixCorrespondance de chemin par défaut ( )

Le raisonnement derrière le nom prefixest qu'une telle configuration d'itinéraire vérifiera si le configuré pathest un préfixe des segments d'URL restants. Cependant, le routeur ne peut faire correspondre que des segments complets , ce qui rend cette dénomination légèrement confuse.

Quoi qu'il en soit, disons que c'est notre configuration de routeur au niveau 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 Routeobjet utilise ici la stratégie de correspondance par défaut, qui est prefix. Cette stratégie signifie que le routeur effectue une itération sur l'ensemble de l'arborescence de configuration et essaie de la comparer à l'URL cible segment par segment jusqu'à ce que l'URL soit entièrement mise en correspondance . Voici comment cela serait fait pour cet exemple:

  1. Parcourez le tableau racine à la recherche d'une correspondance exacte pour le premier segment d'URL - users.
  2. 'products' !== 'users', alors sautez cette branche. Notez que nous utilisons un contrôle d'égalité plutôt qu'un .startsWith()ou .includes()- seuls les segments complets comptent!
  3. :othercorrespond à n'importe quelle valeur, donc c'est une correspondance. Cependant, l'URL cible n'est pas encore entièrement appariée (nous devons encore faire correspondre jameset articles), le routeur recherche donc des enfants.
    • Le seul enfant de :otherest tricks, qui n'est !== 'james'donc pas une correspondance.
  4. Angular revient ensuite au tableau racine et continue à partir de là.
  5. 'user' !== 'users, sauter la branche.
  6. 'users' === 'users- le segment correspond. Cependant, ce n'est pas encore une correspondance complète, nous devons donc rechercher des enfants (comme à l'étape 3).
    • 'permissions' !== 'james', sauter.
    • :userIDcorrespond à tout, nous avons donc une correspondance pour le jamessegment. Cependant, ce n'est toujours pas une correspondance complète, nous devons donc rechercher un enfant qui correspondrait articles.
      1. Nous pouvons voir qu'il :userIDa une route enfant articles, ce qui nous donne une correspondance complète! Ainsi, l'application rend UserArticlesComponent.

fullCorrespondance URL complète ( )

Exemple 1

Imaginez maintenant que l' usersobjet 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 tel é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 ne correspond pas car la configuration du chemin usersavec pathMatch: fullne correspond pas à l'URL complète, qui est users/james/articles.
  2. Puisqu'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 ne rend rien .

Exemple 2

Et si nous avions ceci à la place:

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

users/:userIDavec des pathMatch: fullallumettes seulementusers/james , c'est donc à nouveau une non-correspondance, 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/articlesreste toujours inégalé. Cherchons des enfants.
    • 'permissions' !== 'james' - sauter.
    • :userID'ne peut correspondre qu'à un seul segment, ce qui serait james. Cependant, c'est une pathMatch: fullroute, et elle doit correspondre james/articles(toute l'URL restante). Ce n'est pas capable de faire ça et donc ce n'est pas un match (donc on saute cette branche)!
  2. Encore une fois, nous n'avons trouvé aucune correspondance pour l'URL et l'application ne rend rien .

Comme vous l'avez peut-être remarqué, une pathMatch: fullconfiguration dit essentiellement ceci:

Ignorez mes enfants et ne me correspond. Si je ne parviens pas à faire correspondre moi-même tous les segments d'URL restants , passez à autre chose.

Redirige

Tout Routece qui a défini un redirectTosera comparé à 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 la prefixstratégie par défaut , une correspondance partielle suffit à 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' - sauter.
  2. 'users' === 'users' - nous avons un match.
  3. Cette correspondance a un redirectTo: 'not-found', qui est appliqué immédiatement .
  4. L'URL cible devient not-found.
  5. Le routeur recommence à correspondre et trouve not-foundimmédiatement une correspondance. L'application rend NotFoundComponent.

Considérez maintenant ce qui se passerait si l' usersitinéraire 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' - sauter.
  2. userscorrespondrait au premier segment de l'URL, mais la configuration de l'itinéraire nécessite une fullcorrespondance, donc ignorez-la.
  3. 'users/:userID'matchs users/james. articlesne correspond toujours pas mais cet itinéraire a des enfants.
    • Nous trouvons un match pour articlesles enfants. L'URL entière est maintenant mise en correspondance et l'application est rendue UserArticlesComponent.

Chemin vide ( path: '')

Le chemin vide est un peu un cas particulier car il peut correspondre à n'importe quel segment sans le «consommer» (donc 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 l'itinéraire correspond. Cependant, toute l'URL n'a pas été mise en correspondance - nous devons encore faire correspondre users!
  • Nous pouvons voir qu'il y a un enfant users, qui correspond au segment restant (et seulement!) 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 résoudrait cela:

  1. welcome ne correspond pas à un segment vide, alors ignorez-le.
  2. path: ''correspond au segment vide. Il a un pathMatch: 'full', qui est également satisfait car nous avons fait correspondre l'URL entière (il y avait un seul segment vide).
  3. Une redirection se welcomeproduit et l'application s'affiche WelcomeComponent.

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

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

Cela n'a vraiment pas trop de sens car Angular a implémenté une protection contre les redirections sans fin - il n'exécute qu'une seule redirection par niveau de routage.

Et quoi path: '**'?

path: '**'correspondra absolument à tout ( af/frewf/321532152/fsaest une correspondance) avec ou sans a pathMatch: 'full', il est donc inutile d'utiliser cette option de configuration.

De plus, comme il correspond à tout, le chemin racine est également inclus, ce qui rend { path: '', redirectTo: 'welcome' }redondant dans cette configuration.

Curieusement, c'est parfaitement bien d'avoir cette configuration:

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

Si nous naviguons vers /welcome, il y path: '**'aura un match et une redirection vers la bienvenue se produira. Cela devrait lancer une boucle sans fin de redirections, mais Angular arrête cela immédiatement et tout fonctionne bien.

Avius
la source
3

La stratégie de correspondance de chemin, l'une parmi 'prefix' ou 'full'. La valeur par défaut est «préfixe».

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

La stratégie de correspondance de chemin "complète" correspond à l'URL entière. Il est important de le faire lors de la redirection de routes à chemin vide. Sinon, comme un chemin vide est le 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 une boucle sans fin.

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

Ayoub Ghozzi
la source