Di Angular, Apa itu 'pathmatch: full' dan apa efeknya?

105

Di sini digunakan pathmatch sebagai full dan ketika saya menghapus pathmatch ini bahkan tidak memuat aplikasi atau menjalankan proyek

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 { }
Chanaka Amarasinghe
sumber

Jawaban:

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

Kasus 1 pathMatch:'full' : Dalam kasus ini, ketika aplikasi diluncurkan di localhost:4200(atau beberapa server), halaman default akan menjadi layar selamat datang, karena url akan menjadihttps://localhost:4200/

Jika https://localhost:4200/gibberishini akan mengarahkan ke layar pageNotFound karena path:'**'wildcard

Kasus 2 pathMatch:'prefix' :

Jika rute memiliki { path: '', redirectTo: 'welcome', pathMatch: 'prefix' }, sekarang ini tidak akan pernah mencapai rute karakter pengganti karena setiap url akan cocok dengan yang path:''ditentukan.

sai amar
sumber
halo, terima kasih atas penjelasan yang jelas untuk contoh ini, tetapi dapatkah Anda memberikan contoh lain dengan jenis rute lain agar benar-benar jelas? (seperti menggunakan contoh dengan rute anak dll ..). terima kasih
sohaieb
penjelasan yang sangat bagus Pak, tetapi dapatkah Anda memberi tahu saya cara mengkonfigurasi dengan 2 tata letak yang berbeda. seperti tata letak bagian dalam dan tata letak luar>
Kapil soni
88

pathMatch = 'full' menghasilkan rute yang dicapai ketika segmen URL yang tidak cocok dan tersisa dari kecocokan URL adalah jalur awalan

pathMatch = 'prefix'memberitahu router untuk mencocokkan rute pengalihan saat URL yang tersisa dimulai dengan jalur awalan rute pengalihan.

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

pathMatch: 'full' artinya, seluruh jalur URL harus cocok dan digunakan oleh algoritme pencocokan rute.

pathMatch: 'prefix' artinya, rute pertama yang jalurnya cocok dengan awal URL dipilih, tetapi kemudian algoritme pencocokan rute terus mencari rute turunan yang cocok di mana sisa URL cocok.

Pardeep Jain
sumber
34

Meskipun secara teknis benar, jawaban lain akan mendapat manfaat dari penjelasan tentang pencocokan URL-ke-rute Angular. Saya tidak berpikir Anda dapat sepenuhnya (memaafkan permainan kata-kata) memahami apa yang pathMatch: fullterjadi jika Anda tidak tahu cara kerja router di tempat pertama.


Mari kita definisikan beberapa hal dasar. Kami akan menggunakan URL ini sebagai contoh: /users/james/articles?from=134#section.

  1. Mungkin sudah jelas, tetapi pertama-tama mari kita tunjukkan bahwa parameter kueri ( ?from=134) dan fragmen ( #section) tidak memainkan peran apa pun dalam pencocokan jalur . Hanya url dasar ( /users/james/articles) yang penting.

  2. Angular membagi URL menjadi beberapa segmen . Segmen dari /users/james/articlesare, tentu saja users, jamesdan articles.

  3. Konfigurasi router adalah struktur pohon dengan simpul akar tunggal. Setiap Routeobjek adalah node, yang mungkin memiliki childrennode, yang pada gilirannya mungkin memiliki node lain childrenatau node daun.

Tujuan dari perute adalah untuk menemukan cabang konfigurasi perute , dimulai dari simpul akar, yang akan cocok dengan semua (!!!) segmen dari URL. Ini penting! Jika Angular tidak menemukan cabang konfigurasi rute yang bisa cocok dengan seluruh URL - tidak lebih dan tidak kurang - itu tidak akan merender apapun .

Misalnya, jika URL target Anda adalah /a/b/ctetapi router hanya dapat mencocokkan salah satu /a/batau /a/b/c/d, maka tidak ada kecocokan dan aplikasi tidak akan merender apa pun.

Akhirnya, rute dengan redirectToberperilaku sedikit berbeda dari rute biasa, dan menurut saya rute tersebut akan menjadi satu-satunya tempat di mana orang benar-benar ingin menggunakannya pathMatch: full. Tapi kita akan membahasnya nanti.

prefixPencocokan jalur default ( )

Alasan di balik nama tersebut prefixadalah bahwa konfigurasi rute seperti itu akan memeriksa apakah yang dikonfigurasi pathadalah awalan dari segmen URL yang tersisa. Namun, router hanya dapat mencocokkan segmen penuh , yang membuat penamaan ini sedikit membingungkan.

Bagaimanapun, katakanlah ini adalah konfigurasi router level root kami:

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

Perhatikan bahwa setiap Routeobjek di sini menggunakan strategi pencocokan default, yaitu prefix. Strategi ini berarti bahwa router melakukan iterasi ke seluruh pohon konfigurasi dan mencoba mencocokkannya dengan segmen URL target dengan segmen sampai URL benar - benar cocok . Begini cara melakukannya untuk contoh ini:

  1. Iterasi di atas larik root untuk mencari pencocokan tepat untuk segmen URL pertama - users.
  2. 'products' !== 'users', jadi lewati cabang itu. Perhatikan bahwa kami menggunakan pemeriksaan kesetaraan daripada .startsWith()atau .includes()- hanya pencocokan segmen penuh yang dihitung!
  3. :othercocok dengan nilai apa pun, jadi cocok. Namun, URL target belum sepenuhnya cocok (kami masih perlu mencocokkan jamesdan articles), sehingga router mencari turunan.
  • Satu-satunya anak :otheryaitu tricks, yang !== 'james', maka tidak cocok.
  1. Angular kemudian menelusuri kembali ke array akar dan berlanjut dari sana.
  2. 'user' !== 'users, lewati cabang.
  3. 'users' === 'users- Segmennya cocok. Namun, ini belum full match, oleh karena itu kita perlu mencari anak-anak (sama seperti di langkah 3).
  • 'permissions' !== 'james', Lewati.
  • :userIDcocok dengan apa pun, sehingga kami memiliki kecocokan untuk jamessegmen tersebut. Namun ini masih belum full match, oleh karena itu kami perlu mencari anak yang mau cocok articles.
    1. Kita bisa melihat yang :userIDmemiliki rute anak articles, yang memberi kita pertandingan penuh! Dengan demikian aplikasi membuat UserArticlesComponent.

fullPencocokan URL lengkap ( )

Contoh 1

Bayangkan sekarang usersobjek konfigurasi rute terlihat seperti ini:

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

Perhatikan penggunaan pathMatch: full. Jika ini masalahnya, langkah 1-5 akan sama, namun langkah 6 akan berbeda:

  1. 'users' !== 'users/james/articles- segmen tidak cocok karena konfigurasi jalur usersdengan pathMatch: fulltidak cocok dengan URL lengkap, yaitu users/james/articles.
  2. Karena tidak ada yang cocok, kami melewatkan cabang ini.
  3. Pada titik ini kami mencapai akhir konfigurasi router tanpa menemukan kecocokan. Aplikasi tidak memberikan apa pun .

Contoh 2

Bagaimana jika kita memiliki ini sebagai gantinya:

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

users/:userIDpathMatch: fullhanya dengan kecocokan users/jamessehingga tidak ada kecocokan sekali lagi, dan aplikasi tidak menampilkan apa pun.

Contoh 3

Mari pertimbangkan ini:

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

Pada kasus ini:

  1. 'users' === 'users- Segmennya cocok, tetapi james/articlestetap tidak tertandingi. Ayo cari anak-anak.
  • 'permissions' !== 'james' - lewati.
  • :userID'hanya dapat mencocokkan satu segmen, yaitu james. Namun, ini adalah pathMatch: fullrute, dan harus cocok james/articles(seluruh URL yang tersisa). Itu tidak dapat melakukan itu dan karenanya itu bukan pertandingan (jadi kami melewatkan cabang ini)!
  1. Sekali lagi, kami gagal menemukan kecocokan untuk URL dan aplikasi tidak membuat apa pun .

Seperti yang mungkin Anda perhatikan, pathMatch: fullkonfigurasi pada dasarnya mengatakan ini:

Abaikan anak-anak saya dan hanya cocokkan saya. Jika saya tidak dapat mencocokkan sendiri semua segmen URL yang tersisa , lanjutkan.

Pengalihan

Semua Routeyang telah menetapkan a redirectToakan dicocokkan dengan URL target sesuai dengan prinsip yang sama. Satu-satunya perbedaan di sini adalah pengalihan diterapkan segera setelah segmen cocok . Artinya jika rute pengalihan menggunakan prefixstrategi default , kecocokan parsial sudah cukup untuk menyebabkan pengalihan . Inilah contoh yang bagus:

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

Untuk URL awal kita ( /users/james/articles), inilah yang akan terjadi:

  1. 'not-found' !== 'users' - Lewati.
  2. 'users' === 'users' - kita ada pertandingan.
  3. Pertandingan ini memiliki redirectTo: 'not-found', yang segera diterapkan .
  4. URL target berubah menjadi not-found.
  5. Router mulai mencocokkan lagi dan langsung menemukan kecocokan not-found. Aplikasi membuat NotFoundComponent.

Sekarang pertimbangkan apa yang akan terjadi jika usersrute tersebut juga memiliki 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' - Lewati.
  2. usersakan cocok dengan segmen pertama dari URL, tetapi konfigurasi rute membutuhkan fullkecocokan, jadi lewati saja.
  3. 'users/:userID'korek api users/james. articlesmasih belum cocok tapi rute ini punya anak.
  • Kami menemukan kecocokan untuk articlesanak-anak. Seluruh URL sekarang cocok dan aplikasi ditampilkan UserArticlesComponent.

Jalur kosong ( path: '')

Jalur kosong adalah kasus khusus karena dapat mencocokkan segmen apa pun tanpa "mengonsumsinya" (jadi turunannya harus mencocokkan segmen itu lagi). Pertimbangkan contoh ini:

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

Katakanlah kita mencoba mengakses /users:

  • path: ''akan selalu cocok, sehingga rutenya cocok. Namun, seluruh URL belum cocok - kami masih harus cocok users!
  • Kita dapat melihat bahwa ada anak users, yang cocok dengan segmen yang tersisa (dan hanya!) Dan kita memiliki kecocokan penuh. Aplikasi membuat BadUsersComponent.

Sekarang kembali ke pertanyaan awal

OP menggunakan konfigurasi router ini:

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

Jika kita menavigasi ke root URL ( /), berikut cara router menyelesaikannya:

  1. welcome tidak cocok dengan segmen kosong, jadi lewati saja.
  2. path: ''cocok dengan segmen kosong. Ini memiliki pathMatch: 'full', yang juga terpenuhi karena kami telah mencocokkan seluruh URL (memiliki satu segmen kosong).
  3. Pengalihan welcometerjadi dan aplikasi ditampilkan WelcomeComponent.

Bagaimana jika tidak ada pathMatch: 'full'?

Sebenarnya, orang akan berharap semuanya berperilaku persis sama. Namun, Angular secara eksplisit mencegah konfigurasi seperti itu ( { path: '', redirectTo: 'welcome' }) karena jika Anda meletakkan ini di Routeatas welcome, itu secara teoritis akan membuat loop pengalihan tanpa akhir. Jadi Angular hanya membuat kesalahan , itulah sebabnya aplikasi tidak berfungsi sama sekali! ( https://angular.io/api/router/Route#pathMatch )

Sebenarnya, ini tidak terlalu masuk akal bagi saya karena Angular juga telah menerapkan perlindungan terhadap pengalihan tanpa akhir seperti itu - ia hanya menjalankan satu pengalihan per tingkat perutean! Ini akan menghentikan semua pengalihan lebih lanjut (seperti yang akan Anda lihat pada contoh di bawah).

Tentang apa path: '**'?

path: '**'akan benar-benar cocok dengan apa pun ( af/frewf/321532152/fsaadalah pertandingan) dengan atau tanpa pathMatch: 'full'.

Juga, karena cocok dengan semuanya, jalur root juga disertakan, yang membuatnya { path: '', redirectTo: 'welcome' }benar-benar mubazir dalam penyiapan ini.

Lucunya, tidak masalah untuk memiliki konfigurasi ini:

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

Jika kita menavigasi ke /welcome, path: '**'akan menjadi pertandingan dan pengalihan untuk menyambut akan terjadi. Secara teoritis ini harus memulai loop pengalihan tanpa akhir tetapi Angular segera menghentikannya (karena perlindungan yang saya sebutkan sebelumnya) dan semuanya berfungsi dengan baik.

Avius
sumber
Saya agak bingung untuk jalur lengkap. Anda sebutkan di Contoh 3 dari pencocokan URL lengkap Ignore my children and only match me. If I am not able to match all of the remaining URL segments myself, then move on. Dimana seperti pada pencocokan jalur lengkap dari bagian Pengalihan yang Anda sebutkan We find a match for articles in the children. The whole URL is now matched and the application renders UserArticlesComponent. Dari apa yang saya pahami seharusnya tidak cocok di Reidrect juga?
rns
Sebagai catatan - saya ignore my childrensendiri yang memberikan penjelasannya. Keraguan ini adalah cara pengembang Angular melihatnya, tetapi ini adalah salah satu prinsip pathMatch: 'full'. Jadi dalam contoh pengalihan yang Anda maksud, pemberitahuan yang pathMath: 'full'diterapkan ke rute kedua ( path: 'users'), yang, karena itu, tidak cocok. Rute yang cocok adalah path: 'users/:userID', yang tidak menggunakan pathMatch: 'full'dan bekerja seperti biasa. Jadi pertama-tama cocok users/jamesdan kemudian kita cari articlespada anak-anaknya (sekali lagi, tidak digunakan pathMatch: 'full').
Avius
3

Strategi pencocokan jalur, salah satu dari 'awalan' atau 'penuh'. Default-nya adalah 'awalan'.

Secara default, router memeriksa elemen URL dari kiri untuk melihat apakah URL cocok dengan jalur yang diberikan, dan berhenti jika ada kecocokan. Misalnya, '/ tim / 11 / pengguna' cocok dengan 'tim /: id'.

Strategi pencocokan jalur 'penuh' cocok dengan seluruh URL. Hal ini penting untuk dilakukan saat mengarahkan rute jalur kosong. Jika tidak, karena jalur kosong adalah awalan dari URL apa pun, router akan menerapkan pengalihan bahkan saat menavigasi ke tujuan pengalihan, membuat loop tanpa akhir.

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

Ayoub Ghozzi
sumber