2016-08-18 15 views
6

Angular 2 rc5 की मेरी समझ के अनुसार, एक और मॉड्यूल (नहीं AppModule) से एक सेवा बनाने के लिए प्रत्येक घटक के लिए एक सिंगलटन, यहां तक ​​कि उन आलसी-लोडेड, हम डॉन के रूप में उपलब्ध करने के लिए उपलब्ध बनाने के लिए कैसे टी उस अन्य मॉड्यूल के providers सरणी में सेवा शामिल है। हम बजाय AppModuleकोणीय 2 सिंगलटन सेवा आलसी लोड मॉड्यूल

According to the docs में RouterModule.forRoot() के साथ निर्यात और आयात परिणाम:

The SharedModule should only provide the UserService when imported by the root AppModule. The SharedModule.forRoot method helps us meet this challenge...the SharedModule does not have providers ...When we add the SharedModule to the imports of the AppModule, we call forRoot. In doing so, the AppModule gains the exported classes and the SharedModule delivers the singleton UserService provider at the same time

मैं वास्तव में कैसे एक 3-पक्ष सेवा (imports सरणी में एक मॉड्यूल के द्वारा उपयोग किया गया सेवा बनाने के लिए संघर्ष कर रहा हूँ के साथ मेरे AppModule) आलसी लोड किए गए मार्गों के लिए उपलब्ध है। मेरे पास इस तृतीय-पक्ष मॉड्यूल पर कोई नियंत्रण नहीं है, इसलिए मैं उस सेवा को NgModule.providers सरणी से उस सेवा को हटा नहीं सकता और इसे RouterModule.forRoot() के अंदर रख सकता हूं क्योंकि मैं अपनी सेवाओं में से एक के साथ हूं।

विशिष्ट सेवा MdIconRegistry है, जो Angular Material 2 alpha 7-3 की MdIconModule के लिए providers में है। इस सेवा का उपयोग svg आइकनों को पंजीकृत करने के लिए किया जाता है जिसे पृष्ठ पर <md-icon svgIcon='iconName'> टैग के साथ प्रदर्शित किया जा सकता है। तो:

  • मैं अपने रूट में MdIconModule आयातित AppModule
  • मैं में मेरी AppComponent

आइकन दिखाई दे रहा है svg माउस रजिस्टर करने के लिए प्रश्न में सेवा का उपयोग किया है और अच्छी तरह से काम करता है, लेकिन केवल मॉड्यूल में जो लॉन्च पर लोड किए गए थे। आलसी लोड मॉड्यूल इन आइकनों को नहीं देख सकते हैं, इसलिए मुझे संदेह है कि कोणीय इंजेक्टर MdIconRegistry सेवा के उसी उदाहरण को इंजेक्शन नहीं दे रहा है।

tl; dr: मैं अपने आलसी लोड किए गए घटकों के लिए एक सिंगलटन मॉड्यूल से एक सिंगलटन मॉड्यूल से सेवा कैसे बना सकता हूं?

Here is a plunker that demonstrates the problem (typescript में कोडित)।

पुनश्च: यह सिर्फ MdIconModule डेवलपर on github.

उत्तर

8
I do not think it has anything to do with the component being lazy-loaded. 

LazyLoadedComponent AppModule का हिस्सा नहीं है का ध्यान मिल गया है - यह LazyModule का हिस्सा है। दस्तावेज़ों के मुताबिक, एक घटक केवल एक मॉड्यूल का हिस्सा हो सकता है। यदि आप LazyLoadedComponent को AppModule में भी जोड़ने का प्रयास करते हैं, तो आपको उस प्रभाव में एक त्रुटि मिलेगी। तो LazyLoadedComponent भी MdIconModule नहीं देख रहा है। आप डीबगर में टेम्पलेट आउटपुट को देखकर इसकी पुष्टि कर सकते हैं - यह अपरिवर्तित है।

<md-icon svgIcon="play"></md-icon> 

समाधान LazyModule को MdIconModule जोड़ने प्रतीत होता है, और जब तक इस अकेले समस्या हल नहीं होती है, यह उत्पादन के लिए एक त्रुटि जोड़ता है।

Error retrieving icon: Error: Unable to find icon with the name ":play"

और टेम्पलेट आउटपुट अब इस तरह दिखता है, इसलिए हम जानते हैं कि यह लोड हो रहा है।

<md-icon role="img" svgicon="play" ng-reflect-svg-icon="play" aria-label="play"></md-icon> 

मैं LazyLoadedComponent से addSvgIconSet करने के लिए कॉल जोड़ा, और कहा कि यह काम कर रहा हो गया है ... इसलिए यह साबित करता है घटक प्रति MdIconRegistry सेवा का एक उदाहरण है - नहीं आप क्या चाहते हैं, लेकिन सही दिशा में जा सकते हैं।

Why is a service provided in a lazy loaded module visible only to that module?

Unlike providers of the modules loaded at launch, providers of lazy loaded modules are module-scoped.

अंतिम अद्यतन: http://plnkr.co/edit/YDyJYu?p=preview

आगे की समीक्षा के बाद, मैं docs में यह पाया -

यहाँ नए अंगुलियों से छूना है! जवाब यहाँ है। MdIconModule आलसी लोड किए गए घटकों के लिए उचित रूप से सेटअप नहीं है ... लेकिन हम आसानी से अपना स्वयं का मॉड्यूल बना सकते हैं जो ठीक तरह से स्थापित है और इसके बजाय इसका उपयोग करें।

import { NgModule } from '@angular/core'; 
import { HttpModule } from '@angular/http'; 

import { MdIcon } from '@angular2-material/icon'; 
import { MdIconRegistry } from '@angular2-material/icon'; 

@NgModule({ 
    imports: [HttpModule], 
    exports: [MdIcon], 
    declarations: [MdIcon] 
}) 
export class MdIconModuleWithProviders { 
    static forRoot(): ModuleWithProviders { 
    return { 
     ngModule: MdIconModuleWithProviders, 
     providers: [ MdIconRegistry ] 
    }; 
    } 
} 

प्लंक अद्यतन और पूरी तरह से काम कर रहा है। (क्षमा करें, वही अपडेट किया गया) ->http://plnkr.co/edit/YDyJYu?p=preview

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

+0

अरे जेम्स आपकी प्रतिक्रिया के लिए बहुत बहुत धन्यवाद। आप 'mdIconModule' को 'LazyModule' में आयात करने के बारे में एक अच्छा बिंदु बनाते हैं और मैं इसे प्रतिबिंबित करने के लिए अपना प्लंकर अपलोड करूंगा। अभी भी एक समस्या है: जैसा कि आपने पाया है, आपको 'addSvgIconSet()' को फिर से कॉल करने की आवश्यकता है क्योंकि 'MDRegistryService' एक सिंगलटन नहीं है। प्रत्येक मॉड्यूल में आइकन सेट लोड करना व्यावहारिक नहीं है, हालांकि इसका मतलब है कि प्रत्येक रूट परिवर्तन पर एक ही 'svg' फ़ाइल के लिए एक नया http अनुरोध किया जाता है। मेरा प्रारंभिक प्रश्न बनी हुई है: मैं इस सेवा को 'Lazy मॉड्यूल' के लिए उपलब्ध एक सिंगलटन ('MdIconRegistry') कैसे बना सकता हूं? – BeetleJuice

+0

सही, मैंने जवाब अपडेट किया। ऐसा लगता है कि यह आलसी लोडिंग के साथ करना है, और दायरा डिजाइन द्वारा प्रतिबंधित है। – James

+0

कोणीय एक सिंगलटन सेवा बनाने के लिए सुविधाएं प्रदान करता है जो आलसी मार्गों पर भी लागू होता है (मैं इसे ओपी में लिंक के साथ चर्चा करता हूं)। इसके लिए आवश्यक है कि मॉड्यूल एक निश्चित तरीके से लिखे जाएं (सेवाओं को 'प्रदाताओं' सरणी में नहीं रखा जाना चाहिए या मॉड्यूल आयात करने वाली हर चीज में इंजेक्शन दिया जाएगा)। यहां चुनौती यह है कि मुझे ऐसी सेवा का सामना करना पड़ रहा है जो केवल एक सिंगलटन के रूप में उपयोगी है, लेकिन जिसका मॉड्यूल "सही तरीका" नहीं लिखा गया है और जिसका मॉड्यूल मेरा कोई नियंत्रण नहीं है। मैंने इसे यहां भी बताया: https://github.com/angular/material2/issues/1071 – BeetleJuice

संबंधित मुद्दे