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.
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.
Angular membagi URL menjadi beberapa segmen . Segmen dari /users/james/articlesare, tentu saja users, jamesdan articles.
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:
- Iterasi di atas larik root untuk mencari pencocokan tepat untuk segmen URL pertama -
users.
'products' !== 'users', jadi lewati cabang itu. Perhatikan bahwa kami menggunakan pemeriksaan kesetaraan daripada .startsWith()atau .includes()- hanya pencocokan segmen penuh yang dihitung!
: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.
- Angular kemudian menelusuri kembali ke array akar dan berlanjut dari sana.
'user' !== 'users, lewati cabang.
'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.
- 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:
'users' !== 'users/james/articles- segmen tidak cocok karena konfigurasi jalur usersdengan pathMatch: fulltidak cocok dengan URL lengkap, yaitu users/james/articles.
- Karena tidak ada yang cocok, kami melewatkan cabang ini.
- 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:
'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)!
- 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:
'not-found' !== 'users' - Lewati.
'users' === 'users' - kita ada pertandingan.
- Pertandingan ini memiliki
redirectTo: 'not-found', yang segera diterapkan .
- URL target berubah menjadi
not-found.
- 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,
},
],
},
];
'not-found' !== 'users' - Lewati.
usersakan cocok dengan segmen pertama dari URL, tetapi konfigurasi rute membutuhkan fullkecocokan, jadi lewati saja.
'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:
welcome tidak cocok dengan segmen kosong, jadi lewati saja.
path: ''cocok dengan segmen kosong. Ini memiliki pathMatch: 'full', yang juga terpenuhi karena kami telah mencocokkan seluruh URL (memiliki satu segmen kosong).
- 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.