2016-01-10 15 views
10

कोणीय 2 में, आप एक घटक के लिए @CanActivate एनोटेशन निर्दिष्ट कर सकते हैं जहां आप यह निर्धारित कर सकते हैं कि घटक सक्रिय होना चाहिए या नहीं। इसका कारण यह नहीं है कि यह इंटरफ़ेस नहीं है क्योंकि घटक से पहले कॉलबैक को कॉल किया जाता है। समस्या यह है कि, मैं उस कॉलबैक में निर्भरता प्राप्त करने के लिए एक तरीका नहीं समझ सकता। और मुझे अपनी सेवा की ज़रूरत है जो मुझे बताती है कि क्या मैं लॉग इन हूं या नहीं (और किसके रूप में) यह निर्धारित करने के लिए कि किसी विशेष घटक को रूटिंग की अनुमति है या नहीं।कोणीय 2: @CanActivate में निर्भरता इंजेक्ट करें?

मैं @CanActivate कॉलबैक में निर्भरता कैसे लगा सकता हूं? मैं ES5 उपयोग कर रहा हूँ, और यह काम नहीं करता:

app.ListsComponent = ng.router.CanActivate([ 
    app.SessionService, 
    function(session, instruction) { 
     console.log(session); 
     return true; 
    } 
])(app.ListsComponent); 

संपादित करें: वैकल्पिक रूप से, मैं घटक पर routerOnActivate जीवन चक्र घटना का उपयोग कर सकते हैं, और this.router.navigate का उपयोग उपयोगकर्ता को दूर भेजने की अगर वे नहीं करना पड़ेगा वहाँ रहना। नकारात्मक पक्ष यह है कि यह ब्राउज़र इतिहास टूट जाता है: अगर मैं तुम्हें एसिंक्रोनस रूप से हर बार जब आप किसी विशेष URL पर पहुंचने, रीडायरेक्ट कर आप बहुत उपयोगी आपके ब्राउज़र में वापस बटन का उपयोग नहीं कर सकते। router.navigate इस तरह की स्थिति के लिए history.pushState के बजाय history.replaceState का उपयोग करने का कोई तरीका है?

+0

DI एक बार समस्या होनी चाहिए [राउटर हुक इंजेक्शन योग्य और कोर के साथ संगत] (https://github.com/angular/angular/issues/7485) हल हो गया है। मील का पत्थर वर्तमान में कोणीय 2 रिलीज उम्मीदवार है। –

उत्तर

1

मैं इसके लिए सबसे अच्छा तरीका है, लेकिन इन लोगों का विस्तार और अपने स्वयं के <router-outlet> का उपयोग करके यह कर यदि जानते हैं और CanActivate विधि ओवरराइड नहीं करें:

https://auth0.com/blog/2015/05/14/creating-your-first-real-world-angular-2-app-from-authentication-to-calling-an-api-and-everything-in-between/

इसके अलावा, आप के बजाय routerOnActivate इस्तेमाल कर सकते हैं।

https://angular.io/docs/js/latest/api/router/OnActivate-interface.html मुझे आशा है कि इस मदद करता है।

+1

धन्यवाद, मैं पहले उसमें भाग लेगा, लेकिन मुझे लगता है कि रूटिंग एपीआई तब से बहुत बदल गया है; मैं उनके उदाहरण काम नहीं कर सका। –

+0

मैं देखता हूं, आप इसके बजाय 'राउटरऑनएक्टिवेट' क्यों नहीं देखते? आप अभी भी घटक को तत्काल प्राप्त करने से बच सकते हैं लेकिन आपके पास किसी भी तरह से इंजेक्शन गुणों तक पहुंच है। https://angular.io/docs/js/latest/api/router/OnActivate-interface.html – Langley

2

आपको इंजेक्टर का उपयोग करके इसे इंजेक्ट करना होगा। बस एक एक परियोजना मैं कर रहा हूँ से त्वरित कॉपी पेस्ट:

@CanActivate((next: ComponentInstruction, prev: ComponentInstruction) => { 

    console.info('CanActivate hook! - can return boolean or Promise'); 

    var injector = Injector.resolveAndCreate([HTTP_PROVIDERS, YourService]); 
    var yourService = injector.get(YourService); 
    // do something with yourService 
    return new Promise(function(resolve, reject) { 
     resolve(true); 
    }); 

}) 

HTTP_PROVIDERS आप पास किया जा सके, तो आपकी सेवा उदाहरण निर्माता में HTTP सेवा इंजेक्शन लगाने के लिए है।

मैं अगले वस्तु का परम पर एक नमूदार डाल करने के लिए इसका इस्तेमाल करते हैं।

@CanActivate((next: ComponentInstruction, prev: ComponentInstruction) => { 

    console.info('properties component CanActivate hook! - can return boolean or Promise'); 
    var injector = Injector.resolveAndCreate([HTTP_PROVIDERS, PropertiesService]); 
    var propertiesService = injector.get(PropertiesService); 
    return new Promise(function(resolve, reject) { 
     next.params['properties'] = propertiesService.getProperties(); 
     resolve(true); 
    }); 

}) 

PropertiesService एक बैकएंड कॉल करता है और एक नमूदार कि गुणों के साथ डेटा का प्रतिनिधित्व करता

+0

इस तरह आपको 'YourService' का नया उदाहरण मिलता है, आप नहीं। यह वांछित नहीं हो सकता है। एक कार्यक्षेत्र एक स्थिर क्षेत्र का उपयोग करके इंजेक्टर को आपके 'AppComponent' को स्टोर करना होगा और फिर इस इंजेक्टर का उपयोग '@CanActivate()' में एक नया बनाने के बजाय करना होगा। –

+0

क्या आप एक सिंगलटन के रूप में सेवा को लागू करने का मतलब है? –

+0

मेरे मामले में मैं सोच रहा हूं कि क्या वास्तव में मायने रखता है .. मैं सेवा में डेटा स्टोर नहीं करता हूं। यह सिर्फ बैकएंड को कॉल करने का एक तरीका प्रदान करता है। तुम क्या सोचते हो? –

7

अधिकांश यहाँ समाधान लोड हो रहा है सब-निर्भरता के साथ समस्याओं को पेश करेंगे रिटर्न: और अगले ऑब्जेक्ट अपने अगले "घटक/राज्य" है पदानुक्रम में कहीं और से, क्योंकि वे एक नया इंजेक्टर बनाते हैं। इसके अलावा, इसके परिणामस्वरूप अतिरिक्त (गैर-साझा) सेवाएं इंस्टॉल की जा रही हैं। मैं https://github.com/angular/angular/issues/4112

में ब्रैंडन द्वारा प्रदान की पैटर्न पालन करने की सलाह उन्होंने इस खनखनाहट का संदर्भ: http://plnkr.co/edit/SF8gsYN1SvmUbkosHjqQ?p=preview

इसका मुख्य विचार एक सिंगलटन इंजेक्टर, जो वह बचाता है जब अनुप्रयोग आरंभ है।यह जड़ निर्भरता आप पहले से ही कॉन्फ़िगर किया है तक पहुँच प्रदान करता है, और आगे के रूप में वे शायद लिए ही थे अपनी सेवाओं को एक सिंगलटन के रूप में साझा करने के लिए अनुमति देता है:

import {Injector} from 'angular2/angular2'; 
let appInjectorRef: Injector; 

export const appInjector = (injector?: Injector):Injector => { 
    if (injector) { 
     appInjectorRef = injector; 
    } 

    return appInjectorRef; 
}; 

bootstrap([ServiceYouNeed]).then((appRef) => { 
    // store a reference to the injector 
    appInjector(appRef.injector); 
}); 
+0

में इसे कैसे पहुंचाया जाए, मैंने कोशिश की लेकिन मैं मार्ग पैराम हल नहीं कर सका। मार्ग दें पैराम: रूटपेरम्स = इंजेक्टर.जेट (रूटपेराम); –

1

यहाँ (https://gist.github.com/clemcke/c5902028a1b0934b03d9) कैसे addInjector() समाधान का परीक्षण करने के लिए है कि @shannon संदर्भ:

beforeEachProviders(()=>[PERSON_SERVICE_PROVIDERS]); 

beforeEach(inject([PersonService],()=>{ 
    let injector = Injector.resolveAndCreate([PERSON_SERVICE_PROVIDERS]); 
    appInjector(injector); 
})); 
0

कोणीय 2.0 अंतिम समाधान:

जब से हम अब एक अलग वर्ग है जो CanActivate लागू करता है तो उस वर्ग को परिभाषित @Injectable हो सकता है, और this उत्तर के अनुसार अपने निर्माता में एक और निर्भरता प्रदान की जा सकती है।

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