जब एंगुलर 2 में ऐप शुरू होता है तो सर्विस कैसे चलाएं


99

मैंने एक सेवा सॉकेट सेवा का निर्माण किया, मूल रूप से यह सॉकेट को प्रारंभ करता है ताकि ऐप को पोर्ट पर सुनने दिया जा सके। यह सेवा कुछ घटकों के साथ सहभागिता भी करती है।

// socket.service.ts

export class SocketService {
    constructor() {
        // Initializes the socket
    }
    ...
}

मुझे पता है कि कोड सॉकेटसर्वर के कंस्ट्रक्टर () में तब ही चलना शुरू होता है जब कोई घटक सॉकेट्स सर्विस का उपयोग करता है।

और आमतौर पर app.ts में कोड इस तरह दिखता है:

// app.ts

import {SocketService} from './socket.service';
...
class App {
    constructor () {}
}
bootstrap(App, [SocketService]);

हालाँकि, मैं चाहता हूं कि जब यह ऐप शुरू हो, तो यह सेवा चले। इसलिए मैंने एक ट्रिक बनाई, बस private _socketService: SocketServiceऐप के कंस्ट्रक्टर () में जोड़ें । तो अब कोड इस तरह दिखते हैं:

// app.ts (नया)

import {SocketService} from './socket.service';
...
class App {
    constructor (private _socketService: SocketService) {}
}
bootstrap(App, [SocketService]);

अब यह काम कर रहा है। समस्या कभी-कभी सॉकेट्स सर्विस के कंस्ट्रक्टर () रन में कोड होती है, कभी-कभी नहीं। तो मुझे इसे सही तरीके से कैसे करना चाहिए? धन्यवाद


इस मार्गदर्शिका ने मेरी मदद की: angular.io/docs/ts/latest/tutorial/…
Marian07

जवाबों:


135

स्टुअर्ट का उत्तर सही दिशा में इंगित करता है, लेकिन APP_INITIALIZER पर जानकारी प्राप्त करना आसान नहीं है। संक्षिप्त संस्करण यह है कि आप अपने किसी अन्य एप्लिकेशन कोड के चलने से पहले आरंभीकरण कोड को चलाने के लिए इसका उपयोग कर सकते हैं। मैंने थोड़ी देर खोजा और यहाँ और यहाँ स्पष्टीकरण पाया , जो मैं उस मामले में संक्षेप में बताऊँगा जब वे वेब से गायब हो जाते हैं।

APP_INITIALIZER को कोणीय / कोर में परिभाषित किया गया है। आप इसे अपने app.module.ts में इस तरह शामिल करते हैं।

import { APP_INITIALIZER } from '@angular/core';

APP_INITIALIZER एक OpaqueToken (या Angular 4 के बाद एक InjectionToken) है जो ApplicationInitStatus सेवा का संदर्भ देता है। ApplicationInitStatus एक बहु प्रदाता है । यह कई निर्भरता का समर्थन करता है और आप इसे अपने प्रदाताओं की सूची में कई बार उपयोग कर सकते हैं। इसका उपयोग इस तरह किया जाता है।

@NgModule({
  providers: [
    DictionaryService,
    {
      provide: APP_INITIALIZER,
      useFactory: (ds: DictionaryService) => () => return ds.load(),
      deps: [DictionaryService],
      multi: true
    }]
})
export class AppModule { }

यह प्रदाता घोषणा DictionaryService.load () विधि को चलाने के लिए ApplicationInitStatus वर्ग को बताता है। लोड () एक वादा लौटाता है और ApplicationInitStatus वादा शुरू होने तक ऐप स्टार्टअप को ब्लॉक कर देता है। लोड () फ़ंक्शन को इस तरह परिभाषित किया गया है।

load(): Promise<any> {
  return this.dataService.getDiscardReasons()
  .toPromise()
  .then(
    data => {
      this.dictionaries.set("DISCARD_REASONS",data);
    }
  )
}

इस तरह सेट करें कि शब्दकोश पहले लोड हो जाता है और ऐप के अन्य हिस्से सुरक्षित रूप से इस पर निर्भर हो सकते हैं।

संपादित करें: इस बात से अवगत रहें कि इससे आपके लिए अप-फ्रंट लोड समय में वृद्धि होगी, हालांकि लंबे समय तक लोड () विधि अपनाती है। यदि आप बचना चाहते हैं कि आप अपने मार्ग पर एक रिज़ॉल्वर का उपयोग कर सकते हैं ।


इसके लिए धन्यवाद ... बहुत मददगार
गौरव जोशी

5
यह स्वीकृत उत्तर होना चाहिए। वर्तमान एक निर्माणकर्ता से एक initविधि तक कोड की केवल एक पंक्ति को स्थानांतरित करता है। जबकि कंस्ट्रक्टरों को वास्तव में जितना संभव हो उतना सरल रखा जाना चाहिए, लेकिन अकेले सोचा कि यह उचित समाधान नहीं करता है। का उपयोग कर रहा APP_INITIALIZERहै।
जेपी दस बर्ज

मुझे नहीं लगता कि चयनित उत्तर गलत है, क्योंकि यह ओपी की समस्या को हल करता है। लेकिन , जैसा कि मुझे कुछ पुस्तकालय के विकास पर समान समस्या है, मैंने एक और प्रश्न खोला है, जहां यह उत्तर पूरी तरह से फिट होगा।
मचाडो

सबसे अच्छा तरीका है
Renil Babu

58

अपने SocketServiceकंस्ट्रक्टर में तर्क को इसके बजाय एक विधि में ले जाएँ और फिर अपने मुख्य घटक के कंस्ट्रक्टर में या कहेंngOnInit

SocketService

export class SocketService{
    init(){
        // Startup logic here
    }
}

एप्लिकेशन

import {SocketService} from './socket.service';
...
class App {
    constructor (private _socketService: SocketService) {
        _socketService.init();
    }
}
bootstrap(App, [SocketService]);

1
मुझे समझ में नहीं आता है कि निर्माता के बजाय विधि में सामान रखने के पीछे तर्क क्या आप यह समझा सकते हैं, विधि में तर्क करने का क्या फायदा है?
परदीप जैन

1
एक क्लीनर दृष्टिकोण imho
inoabrian

12
कन्स्ट्रक्टर्स जितना संभव हो उतना सरल होना चाहिए (सामान्य रूप से केवल इंजेक्शन अंक), यदि आपको अतिरिक्त तर्क जोड़ने की आवश्यकता है तो ngOnInit हुक का उपयोग करें।
सर्जियो

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

1
@CodyBugstein यह आपके उपयोग के मामले पर निर्भर करता है। अगर यह सिर्फ आग है और भूल जाओ, तो बस async विधि को बुलाओ। यदि आपको परिणाम के लिए प्रतीक्षा करने की आवश्यकता है तो आप Promiseअपनी init()विधि से वापस लौट सकते हैं और फिर आवश्यकतानुसार श्रृंखला कर सकते हैं । जो भी मामला हो सकता है, लेकिन संभवत: मुश्किल होगा और विवरणों पर काम करने के लिए आपके ऊपर होगा। यदि आपको और मदद की आवश्यकता है तो आप हमेशा अपने सटीक मुद्दे के विवरण के साथ एक प्रश्न पोस्ट कर सकते हैं और समुदाय आपकी सहायता करने में प्रसन्न होगा।
SnareChops


1

सेवा निर्माता बनाने का प्रयास करें और फिर इसे अपने घटक के ngOnInit () में कॉल करें।

  • सेवा मॉड्यूल

 export class SocketService {
    constructor() { }
        getData() {
            //your code Logic
        }
}

  • अंग

export class AppComponent {
    public record;  
    constructor(private SocketService: DataService){ }
    ngOnInit() {        
        this.SocketService.getData()
        .subscribe((data:any[]) => {
            this.record = data;
        });   
  }  
}       

उम्मीद है की यह मदद करेगा।


1
@ होंगबो चाहता है कि ऐप के शुरू होने पर सेवा चले, एक विशेष घटक में नहीं जो सेवा का उपयोग कर रहा हो
Jarod Moser

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