तकनीकी रूप से सही होने पर, अन्य उत्तर कोणीय के URL से मार्ग मिलान के स्पष्टीकरण से लाभान्वित होंगे। मुझे नहीं लगता कि आप पूरी तरह से (दंड को क्षमा कर सकते हैं) समझ सकते हैं कि pathMatch: fullअगर आपको नहीं पता कि राउटर पहले स्थान पर कैसे काम करता है।
आइए पहले कुछ बुनियादी बातों को परिभाषित करें। हम एक उदाहरण के रूप में इस URL का उपयोग करेंगे: /users/james/articles?from=134#section।
यह स्पष्ट हो सकता है लेकिन आइए सबसे पहले बताते हैं कि क्वेरी पैरामीटर ( ?from=134) और टुकड़े ( #section) पथ मिलान में कोई भूमिका नहीं निभाते हैं । केवल आधार url ( /users/james/articles) मायने रखता है।
कोणीय खंडों में URL विभाजित करता है । के खंड /users/james/articles, निश्चित रूप से users, jamesऔर हैं articles।
राउटर कॉन्फ़िगरेशन एक एकल रूट नोड के साथ एक ट्री संरचना है। प्रत्येक Routeऑब्जेक्ट एक नोड है, जिसमें नोड हो सकते हैं children, जो बदले में अन्य हो सकते हैं childrenया पत्ती नोड हो सकते हैं।
राउटर का लक्ष्य एक राउटर कॉन्फ़िगरेशन ब्रांच को खोजना है , जो रूट नोड पर शुरू होता है, जो URL के सभी (!!!) सेगमेंट से मेल खाता होगा । यह महत्वपूर्ण है! यदि एंगुलर को एक रूट कॉन्फ़िगरेशन ब्रांच नहीं मिलती है, जो पूरे URL से मेल खा सके - कोई अधिक और कोई कम नहीं - यह कुछ भी रेंडर नहीं करेगा ।
उदाहरण के लिए, यदि आपका लक्ष्य URL है, /a/b/cलेकिन राउटर केवल /a/bया तो मैच करने में सक्षम है या नहीं /a/b/c/d, तो कोई मिलान नहीं है और एप्लिकेशन कुछ भी प्रस्तुत नहीं करेगा।
अंत में, नियमित मार्गों की तुलना में थोड़ा अलग redirectToतरीके से व्यवहार करने वाले मार्ग, और मुझे लगता है कि वे एकमात्र स्थान होंगे जहां कोई भी वास्तव में उपयोग करना चाहेगाpathMatch: full । लेकिन हम इसे बाद में प्राप्त करेंगे।
डिफ़ॉल्ट ( prefix) पथ मिलान
नाम के पीछे तर्क यह prefixहै कि इस तरह के मार्ग विन्यास की जांच करेगा कि क्या कॉन्फ़िगर pathशेष URL खंडों का एक उपसर्ग है। हालाँकि, राउटर केवल पूर्ण खंडों का मिलान करने में सक्षम है , जो इस नामकरण को थोड़ा भ्रमित करता है।
वैसे भी, मान लें कि यह हमारा रूट-स्तरीय राउटर कॉन्फ़िगरेशन है:
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,
},
],
},
],
},
];
ध्यान दें कि यहां हर एक Routeऑब्जेक्ट डिफ़ॉल्ट मिलान रणनीति का उपयोग करता है, जो है prefix। इस रणनीति का मतलब है कि राउटर पूरे कॉन्फ़िगरेशन ट्री पर पुनरावृत्ति करता है और इसे तब तक लक्ष्य URL सेगमेंट के विरुद्ध मिलान करने की कोशिश करता है जब तक कि URL पूरी तरह से बंद न हो जाए । इस उदाहरण के लिए यह कैसे किया जाएगा:
- रूट सरणी पर पहले URL सेगमेंट के लिए सटीक मिलान की तलाश में -
users।
'products' !== 'users', इसलिए उस शाखा को छोड़ें। ध्यान दें कि हम केवल .startsWith()या .includes()केवल पूर्ण खंड मिलान संख्या के बजाय एक समानता जांच का उपयोग कर रहे हैं !
:otherकिसी भी मूल्य से मेल खाता है, इसलिए यह एक मैच है। हालांकि, लक्ष्य URL अभी पूरी तरह से मेल नहीं खाता है (हमें अभी भी मिलान करने की आवश्यकता है ) jamesऔर articles, इस प्रकार राउटर बच्चों के लिए दिखता है।
- का एकमात्र बच्चा
:otherहै tricks, जो !== 'james'एक मैच नहीं है।
- कोणीय फिर मूल सरणी पर वापस जाता है और वहां से जारी रहता है।
'user' !== 'users, शाखा छोड़ें।
'users' === 'users- खंड से मेल खाता है। हालाँकि, यह अभी तक पूर्ण मैच नहीं है, इसलिए हमें बच्चों की तलाश करने की जरूरत है (जैसा कि चरण 3 में है)।
'permissions' !== 'james', इसे छोड़।
:userIDकुछ भी मेल खाता है, इस प्रकार हमारे पास jamesसेगमेंट के लिए एक मैच है । हालाँकि यह अभी भी एक पूर्ण मैच नहीं है, इस प्रकार हमें एक बच्चे की तलाश करने की आवश्यकता है जो कि मेल खाए articles।
- हम देख सकते हैं कि
:userIDएक बाल मार्ग है articles, जो हमें एक पूर्ण मैच देता है! इस प्रकार एप्लिकेशन रेंडर करता है UserArticlesComponent।
पूर्ण URL ( full) मिलान
उदाहरण 1
अब कल्पना कीजिए कि usersमार्ग विन्यास वस्तु इस तरह दिखती है:
{
path: 'users',
component: UsersComponent,
pathMatch: 'full',
children: [
{
path: 'permissions',
component: UsersPermissionsComponent,
},
{
path: ':userID',
component: UserComponent,
children: [
{
path: 'comments',
component: UserCommentsComponent,
},
{
path: 'articles',
component: UserArticlesComponent,
},
],
},
],
}
के उपयोग पर ध्यान दें pathMatch: full। अगर ऐसा होता, तो चरण 1-5 समान होता, हालाँकि चरण 6 अलग होगा:
'users' !== 'users/james/articles- खंड करता नहीं से मेल खाते हैं क्योंकि पथ विन्यास usersके साथ pathMatch: fullपूर्ण URL है, जो मेल नहीं खाता users/james/articles।
- चूंकि कोई मेल नहीं है, हम इस शाखा को छोड़ रहे हैं।
- इस बिंदु पर हम एक मैच पाए बिना राउटर कॉन्फ़िगरेशन के अंत में पहुंच गए। अनुप्रयोग कुछ भी नहीं प्रदान करता है ।
उदाहरण 2
अगर हमारे पास इसके बजाय क्या था:
{
path: 'users/:userID',
component: UsersComponent,
pathMatch: 'full',
children: [
{
path: 'comments',
component: UserCommentsComponent,
},
{
path: 'articles',
component: UserArticlesComponent,
},
],
}
users/:userIDpathMatch: fullकेवल मैचों के साथ users/jamesइस प्रकार यह एक बार फिर से मैच नहीं है, और एप्लिकेशन कुछ भी नहीं प्रदान करता है।
उदाहरण 3
आइए इस पर विचार करें:
{
path: 'users',
children: [
{
path: 'permissions',
component: UsersPermissionsComponent,
},
{
path: ':userID',
component: UserComponent,
pathMatch: 'full',
children: [
{
path: 'comments',
component: UserCommentsComponent,
},
{
path: 'articles',
component: UserArticlesComponent,
},
],
},
],
}
इस मामले में:
'users' === 'users- सेगमेंट मेल खाता है, लेकिन james/articlesअभी भी बेजोड़ है। चलो बच्चों की तलाश करते हैं।
'permissions' !== 'james' - छोड़ें।
:userID'केवल एक ही खंड से मेल खा सकता है, जो होगा james। हालाँकि, यह एक pathMatch: fullमार्ग है, और इसे james/articles(संपूर्ण शेष URL) से मेल खाना चाहिए । यह ऐसा करने में सक्षम नहीं है और इस तरह यह एक मैच नहीं है (इसलिए हम इस शाखा को छोड़ देते हैं)!
- फिर से, हम URL के लिए कोई भी मिलान खोजने में विफल रहे और एप्लिकेशन कुछ भी नहीं प्रदान करता है ।
जैसा कि आपने देखा होगा, एक pathMatch: fullकॉन्फ़िगरेशन मूल रूप से यह कह रहा है:
मेरे बच्चों को नजरअंदाज करें और केवल मेरी बराबरी करें। यदि मैं स्वयं बचे हुए सभी URL खंडों का मिलान करने में सक्षम नहीं हूं, तो आगे बढ़ें।
पुनर्निर्देश
Routeजिस किसी ने परिभाषित redirectToकिया है, उसी सिद्धांतों के अनुसार लक्ष्य URL के विरुद्ध मिलान किया जाएगा। यहाँ एकमात्र अंतर यह है कि खंड के मिलान होते ही पुनर्निर्देश लागू हो जाता है । इसका मतलब यह है कि यदि कोई रीडायरेक्टिंग रूट डिफ़ॉल्ट prefixरणनीति का उपयोग कर रहा है , तो एक आंशिक मैच एक रीडायरेक्ट का कारण बनने के लिए पर्याप्त है । यहाँ एक अच्छा उदाहरण है:
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,
},
],
},
];
हमारे प्रारंभिक URL के लिए ( /users/james/articles), यहाँ क्या होगा:
'not-found' !== 'users' - इसे छोड़।
'users' === 'users' - हमारा मैच है।
- इस मैच में एक है
redirectTo: 'not-found', जो तुरंत लागू किया जाता है ।
- लक्ष्य URL में बदल जाता है
not-found।
- राउटर फिर से मेल खाना शुरू करता है और
not-foundतुरंत एक मैच ढूंढता है। एप्लिकेशन रेंडर करता है NotFoundComponent।
अब विचार करें कि यदि usersमार्ग भी होता तो क्या होता 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' - इसे छोड़।
usersURL के पहले खंड से मेल खाएगा, लेकिन मार्ग कॉन्फ़िगरेशन के लिए एक fullमिलान की आवश्यकता होती है , इस प्रकार इसे छोड़ दें।
'users/:userID'मेल खाता है users/james। articlesअभी भी मिलान नहीं हुआ है लेकिन इस मार्ग में बच्चे हैं।
- हम
articlesबच्चों के लिए एक मैच पाते हैं । पूरे URL का अब मिलान हो गया है और एप्लिकेशन रेंडर हो गया है UserArticlesComponent।
खाली पथ ( path: '')
खाली रास्ता एक विशेष मामला है, क्योंकि यह किसी भी खंड को "उपभोग" किए बिना मेल कर सकता है (इसलिए यह बच्चों को उस खंड से मेल खाना होगा)। इस उदाहरण पर विचार करें:
const routes: Routes = [
{
path: '',
children: [
{
path: 'users',
component: BadUsersComponent,
}
]
},
{
path: 'users',
component: GoodUsersComponent,
},
];
मान लें कि हम एक्सेस करने का प्रयास कर रहे हैं /users:
path: ''हमेशा मेल खाता है, इस प्रकार रूट मैच करता है। हालाँकि, पूरे URL का मिलान नहीं हुआ है - हमें अभी भी मिलान करने की आवश्यकता है users!
- हम देख सकते हैं कि एक बच्चा है
users, जो शेष (और केवल!) खंड से मेल खाता है और हमारे पास एक पूर्ण मैच है। एप्लिकेशन रेंडर करता है BadUsersComponent।
अब मूल प्रश्न पर वापस आते हैं
ओपी ने इस राउटर कॉन्फ़िगरेशन का उपयोग किया:
const routes: Routes = [
{
path: 'welcome',
component: WelcomeComponent,
},
{
path: '',
redirectTo: 'welcome',
pathMatch: 'full',
},
{
path: '**',
redirectTo: 'welcome',
pathMatch: 'full',
},
];
यदि हम रूट URL ( /) पर नेविगेट कर रहे हैं , तो यहां बताया गया है कि राउटर कैसे हल करेगा:
welcome एक खाली खंड से मेल नहीं खाता है, इसलिए इसे छोड़ें।
path: ''खाली खंड से मेल खाता है। यह एक है pathMatch: 'full', जो भी संतुष्ट है क्योंकि हम पूरे URL से मेल खाते हैं (इसमें एक खाली खंड था)।
- एक पुनर्निर्देशन
welcomeहोता है और अनुप्रयोग प्रस्तुत करता है WelcomeComponent।
अगर नहीं होता तो क्या होता pathMatch: 'full'?
वास्तव में, किसी को पूरी तरह से एक ही व्यवहार करने की उम्मीद होगी। हालांकि, कोणीय स्पष्ट रूप से इस तरह के कॉन्फ़िगरेशन ( { path: '', redirectTo: 'welcome' }) को रोकता है क्योंकि यदि आप इसे Routeऊपर रखते हैं welcome, तो यह सैद्धांतिक रूप से पुनर्निर्देश का अंतहीन लूप बनाएगा। तो कोणीय सिर्फ एक त्रुटि फेंकता है , यही वजह है कि आवेदन बिल्कुल काम नहीं करेगा! ( https://angular.io/api/router/Route#pathMatch )
यह वास्तव में बहुत ज्यादा मायने नहीं रखता है क्योंकि कोणीय ने अंतहीन पुनर्निर्देशों के खिलाफ एक सुरक्षा को लागू किया है - यह केवल रूटिंग प्रति रूटिंग स्तर को चलाता है।
किस बारे में path: '**'?
path: '**'के साथ या उसके बिना बिल्कुल कुछ भी मेल खाता है ( af/frewf/321532152/fsaएक मैच है) pathMatch: 'full', इसलिए इस कॉन्फ़िगरेशन विकल्प का उपयोग करने का कोई मतलब नहीं है।
इसके अलावा, चूंकि यह सब कुछ से मेल खाता है, रूट पथ भी शामिल है, जो { path: '', redirectTo: 'welcome' }इस सेटअप में अनावश्यक बनाता है ।
पूरी तरह से पर्याप्त है, यह इस विन्यास के लिए पूरी तरह से ठीक है:
const routes: Routes = [
{
path: '**',
redirectTo: 'welcome'
},
{
path: 'welcome',
component: WelcomeComponent,
},
];
यदि हम नेविगेट करते हैं /welcome, path: '**'तो एक मैच होगा और स्वागत करने के लिए एक पुनर्निर्देशन होगा। यह एक अंतहीन लूप को पुनर्निर्देशित करना चाहिए, लेकिन कोणीय तुरंत बंद हो जाता है और पूरी चीज ठीक काम करती है।