Was ist in Angular "Pathmatch: voll" und welchen Effekt hat es?

98

Hier wird Pathmatch als voll verwendet und wenn ich diesen Pathmatch lösche, wird nicht einmal die App geladen oder das Projekt ausgeführt

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
quelle

Antworten:

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

Fall 1 pathMatch:'full' : In diesem Fall wird beim Starten der App auf localhost:4200(oder einem Server) die Standardseite als Begrüßungsbildschirm angezeigt, da die URL lautethttps://localhost:4200/

Wenn https://localhost:4200/gibberishdies aufgrund eines Platzhalters zum pageNotFound- Bildschirm umgeleitet wirdpath:'**'

Fall 2 pathMatch:'prefix' :

Wenn die Routen haben { path: '', redirectTo: 'welcome', pathMatch: 'prefix' }, wird dies jetzt niemals die Wildcard-Route erreichen, da jede URL mit der path:''definierten übereinstimmen würde .

Sai Amar
quelle
Hallo, danke für die klare Erklärung zu diesem Beispiel, aber können Sie als weiteres Beispiel eine andere Art von Routen nennen, um es bitte ganz klar zu machen? (wie ein Beispiel mit Kinderrouten usw.). danke
sohaieb
Wirklich nette Erklärung, Sir, aber können Sie mir sagen, wie man mit 2 verschiedenen Layouts konfiguriert. Wie inneres Layout und äußeres Layout>
Kapil soni
86

pathMatch = 'full' führt zu einem Routentreffer, wenn die verbleibenden, nicht übereinstimmenden Segmente der URL mit dem Präfixpfad übereinstimmen

pathMatch = 'prefix'Weist den Router an, mit der Umleitungsroute übereinzustimmen, wenn die verbleibende URL mit dem Präfixpfad der Umleitungsroute beginnt .

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

pathMatch: 'full' bedeutet, dass der gesamte URL-Pfad übereinstimmen muss und vom Routenanpassungsalgorithmus verwendet wird.

pathMatch: 'prefix' bedeutet, dass die erste Route ausgewählt wird, bei der der Pfad mit dem Beginn der URL übereinstimmt, der Routenanpassungsalgorithmus jedoch weiterhin nach übereinstimmenden untergeordneten Routen sucht, bei denen der Rest der URL übereinstimmt.

Pardeep Jain
quelle
15

Obwohl technisch korrekt, würden die anderen Antworten von einer Erklärung des URL-zu-Route-Abgleichs von Angular profitieren. Ich glaube nicht, dass Sie vollständig verstehen können (entschuldigen Sie das Wortspiel), was pathMatch: fullpassiert, wenn Sie nicht wissen, wie der Router überhaupt funktioniert.


Lassen Sie uns zunächst einige grundlegende Dinge definieren. Wir werden diese URL als Beispiel verwenden : /users/james/articles?from=134#section.

  1. Es mag offensichtlich sein, aber lassen Sie uns zunächst darauf hinweisen, dass die Abfrageparameter ( ?from=134) und Fragmente ( #section) beim Pfadabgleich keine Rolle spielen . Nur die Basis-URL ( /users/james/articles) ist wichtig.

  2. Angular teilt URLs in Segmente auf . Die Segmente /users/james/articlessind, natürlich users, jamesund articles.

  3. Die Routerkonfiguration ist eine Baumstruktur mit einem einzelnen Stammknoten. Jedes RouteObjekt ist ein Knoten, der childrenKnoten haben kann , die wiederum andere childrenoder Blattknoten haben können.

Das Ziel des Routers ist es, einen Router - Konfiguration zu finden Zweig , am Wurzelknoten beginnen, die passen würden genau all (!!!) Segmente der URL. Das ist entscheidend! Wenn Angular keine Route Konfigurationszweig finden , die die passen könnten ganze URL - nicht mehr und nicht weniger - es wird nicht machen nichts .

Wenn beispielsweise Ihre Ziel-URL lautet /a/b/c, der Router jedoch nur entweder /a/boder übereinstimmen kann /a/b/c/d, gibt es keine Übereinstimmung, und die Anwendung rendert nichts.

Schließlich redirectToverhalten sich Routen mit etwas anders als normale Routen, und es scheint mir, dass sie der einzige Ort sind, an dem jemand wirklich jemals etwas nutzen möchte pathMatch: full. Aber wir werden später darauf zurückkommen.

Standard ( prefix) Pfadübereinstimmung

Der Grund für den Namen prefixist, dass eine solche Routenkonfiguration prüft, ob die Konfiguration pathein Präfix der verbleibenden URL-Segmente ist. Der Router kann jedoch nur vollständige Segmente abgleichen , was diese Benennung etwas verwirrend macht.

Nehmen wir an, dies ist unsere Routerkonfiguration auf Root-Ebene:

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

Beachten Sie, dass jedes einzelne RouteObjekt hier die Standard-Matching-Strategie verwendet prefix. Diese Strategie bedeutet, dass der Router den gesamten Konfigurationsbaum durchläuft und versucht, ihn segmentweise mit der Ziel-URL abzugleichen, bis die URL vollständig übereinstimmt . So würde es für dieses Beispiel gemacht:

  1. Durchlaufen Sie das Root-Array und suchen Sie nach einer genauen Übereinstimmung für das erste URL-Segment users.
  2. 'products' !== 'users'Überspringen Sie also diesen Zweig. Beachten Sie, dass wir eine Gleichheitsprüfung anstelle einer .startsWith()oder verwenden .includes()- nur vollständige Segmentübereinstimmungen zählen!
  3. :otherEntspricht einem beliebigen Wert, es ist also eine Übereinstimmung. Die Ziel-URL ist jedoch noch nicht vollständig übereinstimmend (wir müssen noch übereinstimmen jamesund articles), daher sucht der Router nach untergeordneten Elementen.
    • Das einzige Kind von :otherist tricks, was !== 'james'daher kein Match ist.
  4. Angular kehrt dann zum Root-Array zurück und fährt von dort fort.
  5. 'user' !== 'users, Zweig überspringen.
  6. 'users' === 'users- Das Segment stimmt überein. Dies ist jedoch noch keine vollständige Übereinstimmung, daher müssen wir nach Kindern suchen (wie in Schritt 3).
    • 'permissions' !== 'james', überspring es.
    • :userIDpasst zu allem, also haben wir eine Übereinstimmung für das jamesSegment. Dies ist jedoch immer noch keine vollständige Übereinstimmung, daher müssen wir nach einem passenden Kind suchen articles.
      1. Wir können sehen, dass :userIDes eine Kinderroute articlesgibt, die uns eine vollständige Übereinstimmung gibt! Somit wird die Anwendung gerendert UserArticlesComponent.

Vollständige fullÜbereinstimmung von URL ( )

Beispiel 1

Stellen Sie sich jetzt vor, dass das usersRoutenkonfigurationsobjekt folgendermaßen aussieht:

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

Beachten Sie die Verwendung von pathMatch: full. Wenn dies der Fall wäre, wären die Schritte 1 bis 5 gleich, jedoch wäre Schritt 6 anders:

  1. 'users' !== 'users/james/articles- Das Segment stimmt nicht überein, da die Pfadkonfiguration usersmit pathMatch: fullnicht mit der vollständigen URL übereinstimmt users/james/articles.
  2. Da es keine Übereinstimmung gibt, überspringen wir diesen Zweig.
  3. Zu diesem Zeitpunkt haben wir das Ende der Routerkonfiguration erreicht, ohne eine Übereinstimmung gefunden zu haben. Die Anwendung rendert nichts .

Beispiel 2

Was wäre, wenn wir dies stattdessen hätten:

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

users/:userIDpathMatch: fullNur mit Übereinstimmungen ist users/jameses also wieder eine Nichtübereinstimmung, und die Anwendung rendert nichts.

Beispiel 3

Betrachten wir Folgendes:

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

In diesem Fall:

  1. 'users' === 'users- Das Segment stimmt überein, james/articlesbleibt aber unübertroffen. Lass uns nach Kindern suchen.
    • 'permissions' !== 'james' - überspringen.
    • :userID'kann nur einem einzelnen Segment entsprechen, was wäre james. Es handelt sich jedoch um eine pathMatch: fullRoute, die übereinstimmen muss james/articles(die gesamte verbleibende URL). Das kann es nicht und daher ist es kein Match (also überspringen wir diesen Zweig)!
  2. Auch hier konnten wir keine Übereinstimmung für die URL finden und die Anwendung rendert nichts .

Wie Sie vielleicht bemerkt haben, pathMatch: fullsagt eine Konfiguration im Grunde Folgendes:

Ignoriere meine Kinder und passe nur zu mir. Wenn ich nicht alle verbleibenden URL-Segmente selbst abgleichen kann, fahren Sie fort.

Weiterleitungen

Alle, Routedie a definiert redirectTohaben, werden nach denselben Prinzipien mit der Ziel-URL abgeglichen. Der einzige Unterschied besteht darin, dass die Umleitung angewendet wird, sobald ein Segment übereinstimmt . Dies bedeutet, dass, wenn eine Umleitungsroute die Standardstrategie verwendet prefix, eine teilweise Übereinstimmung ausreicht, um eine Umleitung zu verursachen . Hier ist ein gutes Beispiel:

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

Für unsere ursprüngliche URL ( /users/james/articles) würde Folgendes passieren:

  1. 'not-found' !== 'users' - überspring es.
  2. 'users' === 'users' - Wir haben ein Match.
  3. Diese Übereinstimmung hat eine redirectTo: 'not-found', die sofort angewendet wird .
  4. Die Ziel-URL ändert sich zu not-found.
  5. Der Router beginnt erneut mit dem Abgleich und findet not-foundsofort einen Abgleich für . Die Anwendung wird gerendert NotFoundComponent.

Überlegen Sie nun, was passieren würde, wenn die usersRoute auch Folgendes hätte 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' - überspring es.
  2. userswürde mit dem ersten Segment der URL übereinstimmen, aber die Routenkonfiguration erfordert eine fullÜbereinstimmung. Überspringen Sie sie daher.
  3. 'users/:userID'Streichhölzer users/james. articlesist immer noch nicht abgestimmt, aber diese Route hat Kinder.
    • Wir finden eine Übereinstimmung für articlesdie Kinder. Die gesamte URL wird jetzt abgeglichen und die Anwendung wird gerendert UserArticlesComponent.

Leerer Pfad ( path: '')

Der leere Pfad ist ein Sonderfall, da er mit jedem Segment übereinstimmen kann , ohne es zu "verbrauchen" (daher müssten seine Kinder diesem Segment erneut entsprechen). Betrachten Sie dieses Beispiel:

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

Nehmen wir an, wir versuchen zuzugreifen /users:

  • path: ''wird immer übereinstimmen, daher stimmt die Route überein. Es wurde jedoch nicht die gesamte URL abgeglichen - wir müssen noch übereinstimmen users!
  • Wir können sehen, dass es ein Kind gibt users, das dem verbleibenden (und einzigen!) Segment entspricht, und wir haben eine vollständige Übereinstimmung. Die Anwendung wird gerendert BadUsersComponent.

Nun zurück zur ursprünglichen Frage

Das OP verwendete diese Routerkonfiguration:

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

Wenn wir zur Root-URL ( /) navigieren, würde der Router dies folgendermaßen beheben:

  1. welcome stimmt nicht mit einem leeren Segment überein, überspringen Sie es also.
  2. path: ''entspricht dem leeren Segment. Es hat eine pathMatch: 'full', was auch zufrieden ist, da wir die gesamte URL abgeglichen haben (es hatte ein einzelnes leeres Segment).
  3. Eine Weiterleitung welcomeerfolgt und die Anwendung wird gerendert WelcomeComponent.

Was wäre, wenn es keine gäbe pathMatch: 'full'?

Eigentlich würde man erwarten, dass sich das Ganze genauso verhält. Allerdings Angular explizit verhindert eine solche Konfiguration ( { path: '', redirectTo: 'welcome' }) , weil , wenn Sie diese setzen Routeoben welcome, wäre es theoretisch eine Endlosschleife von Umleitungen erstellen. Angular gibt also nur einen Fehler aus , weshalb die Anwendung überhaupt nicht funktionieren würde! ( https://angular.io/api/router/Route#pathMatch )

Dies ist wirklich nicht sehr sinnvoll, da Angular einen Schutz gegen endlose Weiterleitungen implementiert hat - es wird nur eine einzige Umleitung pro Routing-Ebene ausgeführt.

Was ist mit path: '**'?

path: '**'passt absolut zu allem ( af/frewf/321532152/fsaist eine Übereinstimmung) mit oder ohne a pathMatch: 'full', daher macht es keinen Sinn, diese Konfigurationsoption zu verwenden.

Da es mit allem übereinstimmt, ist auch der Stammpfad enthalten, was { path: '', redirectTo: 'welcome' }in diesem Setup überflüssig wird.

Lustigerweise ist es vollkommen in Ordnung, diese Konfiguration zu haben:

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

Wenn wir zu navigieren /welcome, path: '**'wird ein Match stattfinden und eine Weiterleitung zur Begrüßung wird stattfinden. Dies sollte eine endlose Schleife von Weiterleitungen auslösen, aber Angular stoppt dies sofort und das Ganze funktioniert einwandfrei.

Avius
quelle
2

Die Pfadanpassungsstrategie, entweder "Präfix" oder "Voll". Standard ist 'Präfix'.

Standardmäßig überprüft der Router die URL-Elemente von links, um festzustellen, ob die URL mit einem bestimmten Pfad übereinstimmt, und stoppt, wenn eine Übereinstimmung vorliegt. Zum Beispiel entspricht '/ team / 11 / user' 'team /: id'.

Die Pfadübereinstimmungsstrategie "Voll" stimmt mit der gesamten URL überein. Dies ist wichtig, wenn Sie Routen mit leeren Pfaden umleiten. Andernfalls wendet der Router die Umleitung an, da ein leerer Pfad ein Präfix einer beliebigen URL ist, auch wenn er zum Umleitungsziel navigiert, wodurch eine Endlosschleife erstellt wird.

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

Ayoub Ghozzi
quelle