RouterModule.forRoot (ROUTES) बनाम RouterModule.forChild (मार्ग)


111

इन दोनों में क्या अंतर है और प्रत्येक के लिए उपयोग के मामले क्या हैं?

डॉक्स वास्तव में मददगार नहीं हैं:

forRoot एक ऐसा मॉड्यूल बनाता है जिसमें सभी निर्देश, दिए गए मार्ग और राउटर सेवा स्वयं होती है।

forChild एक ऐसा मॉड्यूल बनाता है जिसमें सभी निर्देश और दिए गए मार्ग शामिल हैं, लेकिन इसमें राउटर सेवा शामिल नहीं है।

मेरा अस्पष्ट अनुमान है कि एक 'मुख्य' मॉड्यूल के लिए है और दूसरा किसी भी आयातित मॉड्यूल के लिए है (क्योंकि उनके पास पहले से ही मुख्य मॉड्यूल से उपलब्ध सेवा होगी), लेकिन मैं वास्तव में एक उपयोग के मामले के बारे में नहीं सोच सकता।


1
क्या आप इस बारे में अधिक विशिष्ट हो सकते हैं कि आप क्या नहीं समझते हैं? आपके द्वारा शाब्दिक रूप से शामिल किया गया उद्धरण आपको बताता है कि अंतर क्या है।
जोंशरशेप

2
मुझे समझ में नहीं आ रहा है कि .forChild () का उपयोग करने का क्या मतलब है। मुझे निर्देश और सेवा के बिना मार्ग कब चाहिए? इस बीच, कृपया उस प्रश्न का उत्तर दें जिसे आपने पोस्ट से हटा दिया है ...
VSO

18
RouterServiceएकल Angular2 अनुप्रयोग के लिए केवल एक होना चाहिए । forRootउस सेवा को इनिशियलाइज़ करेगा और उसे कुछ रूट कॉन्फ़िगर के साथ DI में forChildरजिस्टर करेगा , जबकि केवल अतिरिक्त रूट कॉन्फ़िगर को पंजीकृत करेगा और Angular2 को बताएगा RouterServiceकि forRootउसने बनाया है।
हैरी निन्ह

@ हरिनिंह: धन्यवाद - यही मैं ढूंढ रहा था। आप प्रारंभिक पंजीकरण के बाहर अतिरिक्त मार्ग क्यों दर्ज करना चाहते हैं? मूर्खतापूर्ण लगता है। मैं अनुमान लगा रहा हूं कि गतिशील रूप से मार्ग बनाने का कोई तरीका नहीं है।
VSO

1
इसे कोणीय राउटर लेखक विजेता द्वारा देखें ।
nikhil mehta

जवाबों:


123

मैं दृढ़ता से इस लेख को पढ़ने का सुझाव देता हूं:

प्रदाताओं के साथ मॉड्यूल

जब आप एक मॉड्यूल आयात करते हैं तो आप आमतौर पर मॉड्यूल वर्ग के संदर्भ का उपयोग करते हैं:

@NgModule({
    providers: [AService]
})
export class A {}

-----------------------------------

@NgModule({
    imports: [A]
})
export class B

इस तरह मॉड्यूल पर पंजीकृत सभी प्रदाताओं Aको रूट इंजेक्टर में जोड़ा जाएगा और पूरे आवेदन के लिए उपलब्ध होगा।

लेकिन इस तरह प्रदाताओं के साथ मॉड्यूल रजिस्टर करने का एक और तरीका है:

@NgModule({
    providers: [AService]
})
class A {}

export const moduleWithProviders = {
    ngModule: A,
    providers: [AService]
};

----------------------

@NgModule({
    imports: [moduleWithProviders]
})
export class B

यह पिछले एक के रूप में एक ही निहितार्थ है।

आप शायद जानते हैं कि आलसी लोड किए गए मॉड्यूल का अपना इंजेक्टर है। तो मान लीजिए कि आप AServiceपूरे आवेदन के लिए उपलब्ध होने के लिए पंजीकरण करना चाहते हैं , लेकिन कुछ BServiceकेवल आलसी लोड किए गए मॉड्यूल के लिए उपलब्ध हैं। आप अपने मॉड्यूल को इस तरह से रिफलेक्टर कर सकते हैं:

@NgModule({
    providers: [AService]
})
class A {}

export const moduleWithProvidersForRoot = {
    ngModule: A,
    providers: [AService]
};

export const moduleWithProvidersForChild = {
    ngModule: A,
    providers: [BService]
};

------------------------------------------

@NgModule({
    imports: [moduleWithProvidersForRoot]
})
export class B

// lazy loaded module    
@NgModule({
    imports: [moduleWithProvidersForChild]
})
export class C

अब BServiceकेवल बाल आलसी लोड किए गए मॉड्यूल के AServiceलिए उपलब्ध होगा और पूरे आवेदन के लिए उपलब्ध होगा।

आप इस तरह निर्यात मॉड्यूल के रूप में ऊपर फिर से लिख सकते हैं:

@NgModule({
    providers: [AService]
})
class A {
    forRoot() {
        return {
            ngModule: A,
            providers: [AService]
        }
    }

    forChild() {
        return {
            ngModule: A,
            providers: [BService]
        }
    }
}

--------------------------------------

@NgModule({
    imports: [A.forRoot()]
})
export class B

// lazy loaded module
@NgModule({
    imports: [A.forChild()]
})
export class C

RouterModule के लिए यह प्रासंगिक कैसे है?

मान लीजिए कि वे दोनों एक ही टोकन का उपयोग कर पहुंच रहे हैं:

export const moduleWithProvidersForRoot = {
    ngModule: A,
    providers: [{provide: token, useClass: AService}]
};

export const moduleWithProvidersForChild = {
    ngModule: A,
    providers: [{provide: token, useClass: BService}]
};

अलग-अलग कॉन्फ़िगरेशन के साथ जब आप tokenएक आलसी लोड किए गए मॉड्यूल से अनुरोध करते हैं तो आपको BServiceयोजनाबद्ध रूप से मिलेगा ।

RouterModule ROUTESसभी मॉड्यूल को विशिष्ट करने के लिए टोकन का उपयोग करता है । चूंकि यह चाहता है कि इस मॉड्यूल के अंदर उपलब्ध आलसी लोडेड मॉड्यूल के लिए विशिष्ट मार्ग (हमारे BService के अनुरूप) यह आलसी लोड किए गए बाल मॉड्यूल के लिए अलग कॉन्फ़िगरेशन का उपयोग करता है:

static forChild(routes: Routes): ModuleWithProviders {
    return {
        ngModule: RouterModule, 
        providers: [{provide: ROUTES, multi: true, useValue: routes}]
    };
}

3
तो दूसरे शब्दों में, हमें forChild () को फ़ीचर मॉड्यूल में कॉल करना चाहिए क्योंकि forRoot () को पहले ही रूट मॉड्यूल में बुलाया गया था और सभी आवश्यक सेवाओं को जोड़ा गया था। इसलिए forRoot () को फिर से कॉल करने से अप्रत्याशित राज्यों को बढ़ावा मिलेगा?
वचबर्न

7
@Wachburn, forRootएक आलसी लोडेड मॉड्यूल में कॉल करने से आलसी लोडेड मॉड्यूल इंजेक्टर में सभी वैश्विक सेवाओं के नए उदाहरण बनेंगे । हां, इससे अप्रत्याशित परिणाम प्राप्त होंगे। इस लेख को भी पढ़ें
मैक्स Koretskyi

1
@Illwsharp, क्यों?
मैक्स कोर्सेटस्की

1
मैं इसे पूरी तरह से समझता हूं। लेकिन Routermodule.foRoot, VS Routermodule.forChild में क्या अंतर है? forRoot और forChild केवल स्थिर विधि है जो पारित किए गए मूल्य के आधार पर बदले में वस्तु देता है। तो ऐप मॉड्यूल में, मैं forChild का उपयोग करने में सक्षम क्यों नहीं हूं ?? इसकी त्रुटि क्यों? मैं एकाधिक forRoot का उपयोग क्यों नहीं कर सकता?
सुभदीप

2
कई बार, उत्तर के साथ सीधे बिंदु पर जाना अच्छा होता है। जानकारी अधिभार ज्यादातर बार और अधिक भ्रम की ओर जाता है।
Adép Marjù Olúwáségun

33

मुझे लगता है कि उत्तर सही हैं लेकिन मुझे लगता है कि कुछ गायब है।
जो चीज़ गायब है वह "क्यों और क्या हल करती है?"।
ठीक है चलो शुरू करें।

पहले कुछ जानकारी का उल्लेख करते हैं:

सभी मॉड्यूल रूट सेवाओं तक पहुंच रखते हैं।
तो यहां तक ​​कि आलसी लोड किए गए मॉड्यूल एक सेवा का उपयोग कर सकते हैं जो कि प्रदान किया गया था app.module
क्या होगा यदि एक आलसी लोडेड मॉड्यूल खुद को एक सेवा प्रदान करेगा जो ऐप मॉड्यूल पहले से ही प्रदान करता है? वहाँ हो जाएगा 2 उदाहरणों।
यह एक समस्या नहीं है, लेकिन कभी-कभी यह है
हम इसे कैसे हल कर सकते हैं? बस उस प्रदाता के साथ एक मॉड्यूल को आलसी लोड किए गए मॉड्यूल पर आयात न करें।

कहानी का अंत।

यह ^ केवल यह दिखाने के लिए था कि आलसी लोड किए गए मॉड्यूल का अपना इंजेक्शन बिंदु है (गैर-आलसी-लोड किए गए मॉड्यूल के विपरीत)।

लेकिन तब क्या होता है जब एक साझा (!) मॉड्यूल घोषित किया जाता है providers, और वह मॉड्यूल आलसी द्वारा आयात किया जाता है और app.module ? फिर, जैसे हमने कहा, दो उदाहरण।

तो हम इसे साझा मॉड्यूल POV में कैसे हल कर सकते हैं? हमें उपयोग करने का एक तरीका चाहिएproviders:[] ! क्यों? क्योंकि वे आलसी और app.module दोनों का आयात करने वाले ऑटो होंगे और हम नहीं चाहते कि जैसा कि हमने देखा कि प्रत्येक का एक अलग उदाहरण होगा।

खैर, यह पता चला है कि हम एक साझा मॉड्यूल की घोषणा कर सकते हैं जो कि नहीं होगा providers:[], लेकिन फिर भी, प्रदाताओं को प्रदान करेगा (क्षमा करें :))

कैसे? ऐशे ही :

यहां छवि विवरण दर्ज करें

ध्यान दें, कोई प्रदाता नहीं।

परंतु

  • अब क्या होगा जब app.module POV सेवा के साथ साझा मॉड्यूल आयात करेगा? कुछ भी तो नहीं।

  • अब क्या होगा जब एक आलसी मॉड्यूल POV के साथ साझा मॉड्यूल को आयात करेगा? कुछ भी तो नहीं।

सम्मेलन के माध्यम से मैनुअल तंत्र में प्रवेश:

आप देखेंगे कि तस्वीरों में प्रदाताओं service1और हैservice2

यह हमें service2आलसी लोड किए गए मॉड्यूल और service1गैर-आलसी मॉड्यूल के लिए आयात करने की अनुमति देता है । ( खांसी ... राउटर .... खांसी )

BTW, कोई भी आपको forRootएक आलसी मॉड्यूल के भीतर कॉल करने के लिए नहीं रोक रहा है । लेकिन आपके पास 2 उदाहरण होंगे क्योंकि app.moduleयह भी करना चाहिए - इसलिए इसे आलसी मॉड्यूल में करें।

इसके अलावा - अगर app.moduleकॉल forRoot(और कोई भी कॉल नहीं forchild) - यह ठीक है, लेकिन रूट इंजेक्टर केवल होगा service1। (सभी ऐप के लिए उपलब्ध)

तो हमें इसकी आवश्यकता क्यों है? मेरे अनुसार :

यह एक साझा मॉड्यूल, करने में सक्षम होने की अनुमति देता विभाजित के माध्यम से - उत्सुक मॉड्यूल और आलसी मॉड्यूल के साथ इस्तेमाल किया जा करने के लिए अपने अलग-प्रदाताओं forRootऔर forChildसम्मेलन। मैं दोहराता हूं: सम्मेलन

बस।

रुको !! सिंगलटन के बारे में एक शब्द भी नहीं ?? तो मैं हर जगह सिंगलटन क्यों पढ़ता हूं?

अच्छा - यह ऊपर के वाक्य में छिपा है ^

यह एक साझा मॉड्यूल की अनुमति देता है, अपने विभिन्न-प्रदाताओं को उत्सुक मॉड्यूल और आलसी मॉड्यूल के साथ उपयोग करने में सक्षम होने के लिए - forRoot और forCild के माध्यम से विभाजित करने में सक्षम बनाता है

सम्मेलन या अधिक सटीक होना करने के लिए - - अगर आप का पालन नहीं होगा - आप होगा (!!!) यह सिंगलटन होने की अनुमति देता नहीं एक सिंगलटन मिलता है।
तो अगर आप केवल लोड forRootमें app.module है, तो आप केवल एक उदाहरण मिलता है क्योंकि आप केवल बुलाना चाहिए forRootमें app.module
BTW - इस बिंदु पर आप के बारे में भूल सकते हैं forChild। आलसी लोड किए गए मॉड्यूल को कॉल नहीं करना चाहिए forRoot- इसलिए आप सिंगल ऑफ़ पीओएल में सुरक्षित हैं।

forRoot और forChild एक अटूट पैकेज नहीं है - यह सिर्फ इतना है कि रूट के लिए कॉल करने का कोई मतलब नहीं है जो स्पष्ट रूप से केवल app.module आलसी मॉड्यूल की क्षमता दिए बिना लोड किया जाएगा , उनकी अपनी सेवाएं हैं, बिना नई सेवाएं बनाए -singleton।

यह सम्मेलन आपको एक अच्छी क्षमता देता है जिसे forChild"केवल आलसी लोड किए गए मॉड्यूल के लिए सेवाओं" का उपभोग करना कहा जाता है ।

यहां एक डेमो रूट प्रदाता सकारात्मक संख्या देता है, आलसी लोडेड मॉड्यूल नकारात्मक संख्या देता है।


1. यहाँ POV क्या है? 2. स्टैकब्लिट्ज़ अब काम नहीं करता है।
निकोलस के

@ निकोलस यह स्टैकब्लिट्ज़ हमेशा थोड़ी देर के बाद चीजों को गड़बड़ कर देता है। मैं नए संस्करण को अपलोड करने का प्रयास करूंगा
रॉय नमिर

26

दस्तावेज़ में स्पष्ट रूप से बताया गया है कि इस भेद का क्या उद्देश्य है: https://angular.io/docs/ts/latest/guide/ngmodule.html####-for-root

केवल रूट एप्लिकेशन मॉड्यूल, AppModule में forRoot को कॉल करें। इसे किसी अन्य मॉड्यूल में कॉल करना, विशेष रूप से एक आलसी लोडेड मॉड्यूल में, इरादे के विपरीत है और एक रनटाइम त्रुटि उत्पन्न करने की संभावना है।

परिणाम आयात करना याद रखें; इसे किसी अन्य @NgModule सूची में न जोड़ें।

हर एप्लिकेशन में एक शुरुआती बिंदु (रूट) होता है, जहां मुख्य रूटिंग सेवा को प्रारंभिक रूप से शुरू किया जाना चाहिए forRoot, जबकि विशेष रूप से "बच्चे" सुविधाओं के लिए मार्गों को अतिरिक्त रूप से पंजीकृत किया जाना चाहिए forChild। यह सबमॉड्यूल और आलसी लोडेड मॉड्यूल्स के लिए बेहद उपयोगी है, जिन्हें एप्लिकेशन स्टार्ट पर लोड नहीं करना पड़ता है, और @ हैरी निन्ह ने कहा कि उन्हें नई सेवा के पंजीकरण के बजाय राउटर सर्विस का पुन: उपयोग करने के लिए कहा जाता है, जो एक रनटाइम त्रुटि का कारण हो सकता है।


2
उन दस्तावेजों को स्थानांतरित किया गया प्रतीत होता है, v2.angular.io/docs/ts/latest/guide/…
पीटरस

1

यदि appRoutes साइट में विभिन्न कार्यों के लिए पथ शामिल है (व्यवस्थापक क्रड, उपयोगकर्ता क्रड, पुस्तक क्रड) और हम उन्हें अलग करना चाहते हैं जो हम बस कर सकते हैं:

 imports: [
    BrowserModule, HttpModule,
    AppRoutingModule,
    RouterModule.forRoot(categoriesRoutes),
    RouterModule.forRoot(auteursRoutes),
  ],

और मार्गों के लिए:

const auteursRoutes:Routes=[
  {path:'auteurs/ajouter',component:CreerAuteurComponent},
]
const categoriesRoutes: Routes = [


  {path:'categories/consulter',component:ConsultercategoriesComponent},
  {path:'categories/getsouscategoriesbyid/:id',component:GetsouscategoriesbyIDComponent},
  {path:'categories/ajout',component:CreerCategorieComponent},
 {path:'categories/:id',component:ModifiercategorieComponent},
 {path:'souscategories/ajout/:id',component:AjoutersouscategorieComponent},
 {path:'souscategories/lecture/:id1',component:SouscategoriesComponent},
 {path:'souscategories/modifier/:id1',component:ModifiersupprimersouscategorieComponent},
  {path:'uploadfile',component:UploadfileComponent},
  {path:'categories',component:ConsultercategoriesComponent},



]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.