In Angular, cos'è "pathmatch: full" e che effetto ha?


101

Qui viene utilizzato il pathmatch come completo e quando elimino questo pathmatch non carica nemmeno l'app o esegue il progetto

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

Risposte:


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

Caso 1 pathMatch:'full' : in questo caso, quando l'app viene avviata su localhost:4200(o qualche server) la pagina predefinita sarà la schermata di benvenuto, poiché l'URL saràhttps://localhost:4200/

Se https://localhost:4200/gibberishquesto reindirizzerà alla schermata pageNotFound a causa del path:'**'carattere jolly

Caso 2 pathMatch:'prefix' :

Se le rotte lo hanno { path: '', redirectTo: 'welcome', pathMatch: 'prefix' }, ora questo non raggiungerà mai la rotta con caratteri jolly poiché ogni URL corrisponderebbe a quello path:''definito.


ciao, grazie per la chiara spiegazione di questo esempio, ma puoi dare come un altro esempio un altro tipo di rotte per renderlo completamente chiaro per favore? (come usare un esempio con percorsi per bambini, ecc.). grazie
sohaieb

davvero bella spiegazione signore, ma potete dirmi come configurare con 2 layout diversi. come layout interno e layout esterno>
Kapil soni

87

pathMatch = 'full' si traduce in un percorso raggiunto quando i segmenti rimanenti e non corrispondenti dell'URL corrispondono al percorso del prefisso

pathMatch = 'prefix'dice al router di abbinare la rotta di reindirizzamento quando l'URL rimanente inizia con il percorso del prefisso della rotta di reindirizzamento.

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

pathMatch: 'full' significa che l'intero percorso dell'URL deve corrispondere e viene utilizzato dall'algoritmo di corrispondenza del percorso.

pathMatch: 'prefix' significa che viene scelta la prima rotta in cui il percorso corrisponde all'inizio dell'URL, ma poi l'algoritmo di corrispondenza della rotta continua a cercare le rotte secondarie corrispondenti in cui corrisponde il resto dell'URL.


24

Sebbene tecnicamente corrette, le altre risposte trarrebbero vantaggio da una spiegazione della corrispondenza tra URL e route di Angular. Non penso che tu possa completamente (scusate il gioco di parole) capire cosa pathMatch: fullfa se non sai come funziona il router in primo luogo.


Definiamo prima alcune cose di base. Useremo questo URL, ad esempio: /users/james/articles?from=134#section.

  1. Può essere ovvio, ma prima facciamo notare che i parametri di query ( ?from=134) e fragments ( #section) non giocano alcun ruolo nella corrispondenza del percorso . Solo l'URL di base ( /users/james/articles) è importante.

  2. Angular divide gli URL in segmenti . I segmenti di /users/james/articlessono, ovviamente users, jamese articles.

  3. La configurazione del router è una struttura ad albero con un singolo nodo radice. Ogni Routeoggetto è un nodo, che può avere childrennodi, che a loro volta possono avere altri childreno essere nodi foglia.

L'obiettivo del router è trovare un ramo di configurazione del router , a partire dal nodo radice, che corrisponda esattamente a tutti (!!!) i segmenti dell'URL. Questo è fondamentale! Se Angular non trova un ramo di configurazione del percorso che potrebbe corrispondere all'intero URL - né più né meno - non renderà nulla .

Ad esempio, se l'URL di destinazione è /a/b/c ma il router è in grado di corrispondere solo a /a/bo /a/b/c/d, allora non c'è corrispondenza e l'applicazione non visualizzerà nulla.

Infine, percorsi con redirectTo comportano in modo leggermente diverso rispetto alle rotte normali, e mi sembra che sarebbero l'unico posto dove chiunque vorrebbe davvero usare pathMatch: full. Ma ci arriveremo più tardi.

prefixCorrispondenza del percorso predefinito ( )

Il ragionamento alla base del nome prefixè che tale configurazione del percorso verificherà se il filepath è un prefisso dei segmenti di URL rimanenti. Tuttavia, il router è in grado di abbinare solo segmenti completi , il che rende questa denominazione leggermente confusa.

Ad ogni modo, diciamo che questa è la nostra configurazione del router a livello di root:

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

Nota che ogni singolo Routeoggetto qui utilizza la strategia di corrispondenza predefinita, che è prefix. Questa strategia significa che il router itera sull'intero albero di configurazione e cerca di abbinarlo all'URL di destinazione segmento per segmento finché l'URL non viene completamente abbinato . Ecco come sarebbe fatto per questo esempio:

  1. Scorri l'array radice cercando una corrispondenza esatta per il primo segmento di URL - users.
  2. 'products' !== 'users', quindi salta quel ramo. Nota che stiamo usando un controllo di uguaglianza invece di un.startsWith() o .includes()- contano solo le corrispondenze di segmenti completi!
  3. :othercorrisponde a qualsiasi valore, quindi è una corrispondenza. Tuttavia, l'URL di destinazione non è ancora completamente abbinato (dobbiamo ancora trovare la corrispondenzajames e articles), quindi il router cerca i bambini.
    • L'unico figlio di :otherè tricks, che è!== 'james' , quindi non una corrispondenza.
  4. Angular quindi torna indietro all'array radice e continua da lì.
  5. 'user' !== 'users, salta ramo.
  6. 'users' === 'users- il segmento corrisponde. Tuttavia, questa non è ancora una corrispondenza completa, quindi dobbiamo cercare i bambini (come nel passaggio 3).
    • 'permissions' !== 'james', salta.
    • :userIDcorrisponde a qualsiasi cosa, quindi abbiamo una corrispondenza per il jamessegmento. Tuttavia questa non è ancora una corrispondenza completa, quindi dobbiamo cercare un bambino che corrisponda articles.
      1. Possiamo vedere che :userIDha un percorso figlio articles, che ci dà una corrispondenza completa! Quindi l'applicazione esegue il rendering UserArticlesComponent.

fullCorrispondenza URL completa ( )

Esempio 1

Immagina ora che l' usersoggetto di configurazione del percorso abbia questo aspetto:

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

Nota l'utilizzo di pathMatch: full. In tal caso, i passaggi 1-5 sarebbero gli stessi, tuttavia il passaggio 6 sarebbe diverso:

  1. 'users' !== 'users/james/articles- il segmento non corrisponde perché la configurazione del percorso userscon pathMatch: fullnon corrisponde all'URL completo, che è users/james/articles.
  2. Poiché non c'è corrispondenza, stiamo saltando questo ramo.
  3. A questo punto siamo giunti alla fine della configurazione del router senza aver trovato una corrispondenza. L'applicazione non restituisce nulla .

Esempio 2

E se invece avessimo questo:

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

users/:userIDpathMatch: fullsolo con fiammiferiusers/james quindi è ancora una volta una non corrispondenza e l'applicazione non restituisce nulla.

Esempio 3

Consideriamo questo:

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

In questo caso:

  1. 'users' === 'users - il segmento corrisponde, ma james/articles rimane ancora senza corrispondenza. Cerchiamo bambini.
    • 'permissions' !== 'james' - Salta.
    • :userID'può corrispondere solo a un singolo segmento, che sarebbe james. Tuttavia, è una pathMatch: fullrotta e deve corrispondere james/articles(l'intero URL rimanente). Non è in grado di farlo e quindi non è una corrispondenza (quindi saltiamo questo ramo)!
  2. Ancora una volta, non siamo riusciti a trovare alcuna corrispondenza per l'URL e l'applicazione non restituisce nulla .

Come avrai notato, una pathMatch: fullconfigurazione fondamentalmente dice questo:

Ignora i miei figli e abbina solo me. Se non sono in grado di abbinare personalmente tutti i segmenti di URL rimanenti , vai avanti.

Reindirizzamenti

Tutto ciò Routeche ha definito a redirectToverrà confrontato con l'URL di destinazione secondo gli stessi principi. L'unica differenza qui è che il reindirizzamento viene applicato non appena un segmento corrisponde . Ciò significa che se un percorso di reindirizzamento utilizza la prefixstrategia predefinita , una corrispondenza parziale è sufficiente per provocare un reindirizzamento . Ecco un buon esempio:

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

Per il nostro URL iniziale ( /users/james/articles), ecco cosa accadrebbe:

  1. 'not-found' !== 'users' - saltalo.
  2. 'users' === 'users' - abbiamo una corrispondenza.
  3. Questa corrispondenza ha un redirectTo: 'not-found', che viene applicato immediatamente .
  4. L'URL di destinazione cambia in not-found.
  5. Il router inizia di nuovo la corrispondenza e trova subito una corrispondenza per not-found. L'applicazione esegue il rendering NotFoundComponent.

Consideriamo ora cosa accadrebbe se il userspercorso avesse anche 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' - saltalo.
  2. userscorrisponderebbe al primo segmento dell'URL, ma la configurazione del percorso richiede una fullcorrispondenza, quindi saltala.
  3. 'users/:userID'partite users/james. articlesnon è ancora abbinato ma questo percorso ha dei bambini.
    • Troviamo una corrispondenza per articlesnei bambini. L'intero URL viene ora trovato e l'applicazione esegue il rendering UserArticlesComponent.

Percorso vuoto ( path: '')

Il percorso vuoto è un po 'un caso speciale perché può abbinare qualsiasi segmento senza "consumarlo" (quindi i suoi figli dovrebbero corrispondere di nuovo a quel segmento). Considera questo esempio:

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

Diciamo che stiamo cercando di accedere /users:

  • path: ''corrisponderà sempre, quindi il percorso corrisponde. Tuttavia, l'intero URL non è stato trovato: dobbiamo ancora trovare una corrispondenzausers !
  • Possiamo vedere che c'è un figlio users, che corrisponde al segmento rimanente (e unico!) E abbiamo una corrispondenza completa. L'applicazione esegue il rendering BadUsersComponent.

Ora torniamo alla domanda originale

L'OP ha utilizzato questa configurazione del router:

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

Se stiamo navigando all'URL di root ( /), ecco come il router lo risolverà:

  1. welcome non corrisponde a un segmento vuoto, quindi saltalo.
  2. path: ''corrisponde al segmento vuoto. Ha un pathMatch: 'full', che è anche soddisfatto perché abbiamo trovato l'intero URL (aveva un singolo segmento vuoto).
  3. Viene eseguito un reindirizzamento a welcomee l'applicazione esegue il rendering WelcomeComponent.

E se non ci fosse stato pathMatch: 'full'?

In realtà, ci si aspetterebbe che l'intera faccenda si comporti esattamente allo stesso modo. Tuttavia, Angular impedisce esplicitamente tale configurazione ( { path: '', redirectTo: 'welcome' }) perché se lo metti Routesopra welcome, teoricamente creerebbe un ciclo infinito di reindirizzamenti. Quindi Angular genera solo un errore , motivo per cui l'applicazione non funzionerebbe affatto! ( https://angular.io/api/router/Route#pathMatch )

Questo non ha davvero molto senso perché Angular ha implementato una protezione contro reindirizzamenti infiniti: esegue solo un singolo reindirizzamento per livello di instradamento.

Di cosa path: '**'?

path: '**'corrisponderà assolutamente a qualsiasi cosa ( af/frewf/321532152/fsaè una corrispondenza) con o senza pathMatch: 'full', quindi non ha senso usare questa opzione di configurazione.

Inoltre, poiché corrisponde a tutto, è incluso anche il percorso di root, il che rende { path: '', redirectTo: 'welcome' } ridondante in questa configurazione.

Stranamente, va benissimo avere questa configurazione:

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

Se navighiamo verso /welcome, path: '**'sarà una partita e un reindirizzamento al benvenuto avverrà. Questo dovrebbe dare il via a un ciclo infinito di reindirizzamenti, ma Angular lo interrompe immediatamente e il tutto funziona bene.


3

La strategia di corrispondenza del percorso, uno tra "prefix" o "full". L'impostazione predefinita è "prefisso".

Per impostazione predefinita, il router controlla gli elementi dell'URL da sinistra per vedere se l'URL corrisponde a un determinato percorso e si ferma quando c'è una corrispondenza. Ad esempio, "/ team / 11 / user" corrisponde a "team /: id".

La strategia di corrispondenza del percorso "completo" corrisponde all'intero URL. È importante farlo quando si reindirizzano rotte con percorsi vuoti. Altrimenti, poiché un percorso vuoto è un prefisso di qualsiasi URL, il router applica il reindirizzamento anche durante la navigazione verso la destinazione di reindirizzamento, creando un loop infinito.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.