2016-04-01 10 views
5

से डेटा के साथ कोणीय 2 बूटस्ट्रैप मैं अपने एप्लिकेशन को उस डेटा से बूटस्ट्रैप करना चाहता हूं जिसे मैं किसी सेवा से पुनर्प्राप्त कर रहा हूं। मैंAJAX कॉल (0)

let dependencies = [ 
    //... a load of dependencies 
    MyService 
]; 

let injector = Injector.resolveAndCreate(dependencies); 
let service: MyService = injector.get(MyService); 

service.getData() // returns observable 
    .toPromise() 
    .then((d) => { 
     // use data to append to dependencies 

     bootstrap(App, dependencies) 
    }); 

यह ठीक काम करता है, की तर्ज पर कुछ कर रही हूँ, लेकिन मैं निर्भरता सरणी दो बार का उपयोग कर पसंद नहीं है, वहाँ ऐसा करने का एक क्लीनर तरीका है? क्या मैं बूटस्ट्रैप के बाद एप्लिकेशन इंजेक्टर में चीजें जोड़ सकता हूं? इसके अलावा मुझे पता है कि बूटस्ट्रैप फ़ंक्शन एक वादा देता है, क्या मैं अपने एजेक्स अनुरोध के समाप्त होने तक एप्लिकेशन के बूटस्ट्रैप को रोकने के लिए इस वादे का उपयोग कर सकता हूं?

बेशक Injector के लिए मैं केवल MyService द्वारा आवश्यक उन निर्भरताओं का उपयोग कर सकता हूं लेकिन यह कल्पना कर सकता है कि यह बहुत भंगुर बनाता है।

उत्तर

5

समस्या यह है कि Angular2 आपको उस पर मुख्य घटक बूटस्ट्रैप करने से पहले एप्लिकेशन संदर्भ और इसके इंजेक्टर तक पहुंच नहीं देता है। इस कोड को स्रोत कोड में देखें: https://github.com/angular/angular/blob/master/modules/angular2/platform/browser.ts#L110

डिफ़ॉल्ट दृष्टिकोण का उपयोग करने के बजाय एक कस्टम बूटस्ट्रैप को लागू करने के लिए एक दृष्टिकोण हो सकता है। ऐसा कुछ ऐसा है जो एप्लिकेशन निर्माण पर अनुप्रयोग निर्माण और बूस्ट्रैपिंग को विभाजित करता है। इस तरह आप दो कार्यों के बीच कुछ लोड करने में सक्षम होंगे।

function customBoostrap(appComponentType, customProviders) { 
    reflector.reflectionCapabilities = new ReflectionCapabilities(); 
    let appProviders = 
    isPresent(customProviders) ? [BROWSER_APP_PROVIDERS, customProviders] : BROWSER_APP_PROVIDERS; 
    var app = platform(BROWSER_PROVIDERS).application(appProviders); 

    var service = app.injector.get(CompaniesService); 

    return service.getCompanies().flatMap((companies) => { 
    var companiesProvider = new Provider('companies', { useValue: data }); 
    return app.bootstrap(appComponentType, [ companiesProvider ]); 
    }).toPromise(); 
} 

और इसे इस तरह का उपयोग करें::

@Component({ 
    (...) 
}) 
export class AppComponent { 
    constructor(@Inject('companies') companies) { 
    console.log(companies); 
    } 
} 

:

customBoostrap(AppComponent, [ 
    HTTP_PROVIDERS, 
    CompaniesService 
]); 

कंपनियों उदाहरण के लिए घटक के भीतर इंजेक्शन के लिए स्वचालित रूप से उपलब्ध हो जाएगा

यहां नमूने के कार्यान्वयन है इस संबंधित plunkr देखें: https://plnkr.co/edit/RbBrQ7KOMoFVNU2ZG5jM?p=preview

इस समय, यह थोड़ा हैकी है लेकिन इस तरह के दृष्टिकोण को सुविधा अनुरोध के रूप में प्रस्तावित किया जा सकता है ...

संपादित

ApplicationRef वर्ग के लिए दस्तावेज़ पर एक नज़र होने के बाद, मैंने देखा कि एक सरल समाधान ;-)

var app = platform(BROWSER_PROVIDERS) 
    .application([BROWSER_APP_PROVIDERS, appProviders]); 

service.getCompanies().flatMap((companies) => { 
    var companiesProvider = new Provider('companies', { useValue: data }); 
    return app.bootstrap(appComponentType, [ companiesProvider ]); 
}).toPromise(); 

यहाँ इसी plunkr है है कि वहाँ: https://plnkr.co/edit/ooMNzEw2ptWrumwAX5zP?p=preview

1

(हमेशा की तरह) @Thierry अपने प्रश्न के दिल में अच्छी तरह से जवाब दिया है, लेकिन मुझे लगता है कि यह अलग से ध्यान देने योग्य है:

मैं बूटस्ट्रैप के बाद आवेदन इंजेक्टर के लिए चीजों जोड़ सकते हैं?

हाँ, घटक है कि उन्हें आवश्यकता के सज्जाकार पर providers या viewProviders में उन्हें घोषणा के द्वारा। उदाहरण के लिए:

//main.ts 
bootstrap(MyComponent) //no dependencies declared 


//my.service.ts 
@Injectable class MyService { public getMessage =() => "foobar" } 


//my.component.ts 
@Component({ 
    selector: 'foo', 
    providers: [MyService] 
    template: `<div>{{mySvc.getMessage()}}</div>` //displays foobar 
}) 
class MyComponent { 
    constructor(private mySvc: MyService){ } 
} 

ध्यान दें कि providers निर्देशों के साथ ही घटकों, (यह DirectiveMetadata पर एक विकल्प है, जिसमें से ComponentMetadata फैली है), जबकि viewProviders केवल कारण है कि स्पष्ट दिया जाता है the difference between them के लिए घटकों पर उपलब्ध है पर इस्तेमाल किया जा सकता है।

आईएमएचओ, bootstrap करने के बजाए जहां भी संभव हो, निर्भरता को इंजेक्ट करने का यह सबसे अच्छा अभ्यास है, क्योंकि यह आपको आवेदन के हिस्से (यानी घटक उप-पेड़) पर दी गई निर्भरता की उपलब्धता को सीमित करने की अनुमति देता है) जहां आप इसे उपलब्ध करना चाहते हैं। यह प्रगतिशील लोडिंग के लिए भी अनुकूल है और एकल बूटस्ट्रैप फ़ाइल में असंख्य असंबद्ध इंजेक्टेबल को कॉन्फ़िगर करने की एसओसी गंध से बचाता है।