मैं कोणीय 2 में एक सिंगलटन सेवा कैसे बनाऊं?


142

मैंने पढ़ा है कि बूटस्ट्रैपिंग के दौरान सभी बच्चों को एक ही उदाहरण साझा करना चाहिए, लेकिन मेरे मुख्य और हेडर घटकों (मुख्य ऐप में हेडर घटक और राउटर-आउटलेट शामिल हैं) में से प्रत्येक मेरी सेवाओं का एक अलग उदाहरण है।

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

bootstrap(MainAppComponent, [ROUTER_PROVIDERS, UserService, FacebookService]);

मेरे लॉगिंग से यह बूटस्ट्रैप कॉल फ़िनिश की तरह दिखता है, फिर मैं देखता हूँ कि FacebookService तब UserService कोड से पहले बनाया जा रहा है, प्रत्येक निर्माणकर्ता रन में, MainAppComponent, HeaderComponent और DefaultCompent:

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


8
क्या आप वाकई है कर रहे हैं नहीं जोड़ा UserServiceऔर FacebookServiceकरने के लिए providersकहीं और?
गुंटर ज़ोचबॉर

जवाबों:


132

जेसन पूरी तरह से सही है! यह निर्भरता इंजेक्शन के काम करने के तरीके के कारण होता है। यह पदानुक्रमित इंजेक्टर पर आधारित है।

Angular2 एप्लिकेशन के भीतर कई इंजेक्टर हैं:

  • रूट एक जिसे आप कॉन्फ़िगर करते हैं जब आपके आवेदन को बूटस्ट्रैप करता है
  • प्रति घटक एक इंजेक्टर। यदि आप किसी अन्य के अंदर एक घटक का उपयोग करते हैं। घटक इंजेक्टर मूल घटक एक का एक बच्चा है। अनुप्रयोग घटक (जिसे आप अपने आवेदन को बढ़ावा देते समय निर्दिष्ट करते हैं) में मूल अभिभावक के रूप में मूल इंजेक्टर है)।

जब Angular2 घटक निर्माता में कुछ इंजेक्ट करने की कोशिश करता है:

  • यह घटक से जुड़े इंजेक्टर में दिखता है। यदि एक मिलान होता है, तो वह इसका उपयोग संबंधित उदाहरण प्राप्त करने के लिए करेगा। यह उदाहरण आलसी है और इस इंजेक्टर के लिए एक सिंगलटन है।
  • यदि इस स्तर पर कोई प्रदाता नहीं है, तो यह मूल इंजेक्टर (और इसी तरह) को देखेगा।

इसलिए यदि आप पूरे आवेदन के लिए एक सिंगलटन चाहते हैं, तो आपको प्रदाता को रूट इंजेक्टर या एप्लिकेशन घटक इंजेक्टर के स्तर पर परिभाषित करने की आवश्यकता है।

लेकिन Angular2 नीचे से इंजेक्टर ट्री को देखेगा। इसका मतलब है कि सबसे निचले स्तर पर प्रदाता का उपयोग किया जाएगा और संबंधित आवृत्ति का दायरा इस स्तर का होगा।

अधिक विवरण के लिए यह प्रश्न देखें:


1
धन्यवाद, यह अच्छी तरह से समझाता है। यह मेरे लिए सिर्फ जवाबी था, क्योंकि यह किन्नर कोणीय 2 के स्व-निहित घटक प्रतिमान के साथ टूटता है। तो चलो कहते हैं कि मैं फेसबुक के लिए घटकों का एक पुस्तकालय बना रहा हूं, लेकिन मैं चाहता हूं कि वे सभी एक सिंगलटन सेवा का उपयोग करें। हो सकता है कि उपयोगकर्ता में लॉग इन की प्रोफ़ाइल तस्वीर दिखाने के लिए एक घटक हो, और पोस्ट करने के लिए एक और। उन घटकों का उपयोग करने वाले ऐप को फ़ेसबुक सेवा को एक प्रदाता के रूप में शामिल करना होगा, भले ही वह स्वयं सेवा का उपयोग न करे? मैं सिर्फ 'getInstance ()' विधि के साथ एक सेवा वापस कर सकता हूं जो वास्तविक सेवा के सिंगलटन का प्रबंधन करता है ...
जेसन गोएमाट

@thierryTemplier मैं इसके विपरीत कैसे करूंगा, मेरे पास एक सामान्य सेवा वर्ग है जिसे मैं कई घटक में इंजेक्ट करना चाहता हूं लेकिन हर बार एक नया उदाहरण त्वरित करता है (प्रदाताओं / निर्देशों के विकल्प को अगले रिलीज में हटा दिया गया और हटाया जाना माना जाता है)
Boban Stojanovski

इतना बेवकूफ होने के लिए क्षमा करें, लेकिन यह मेरे लिए स्पष्ट नहीं है कि आप एक एकल सेवा कैसे बनाते हैं, क्या आप अधिक विस्तार से बता सकते हैं?
गोजो कुदोर

तो, एक सेवा के एक ही उदाहरण के साथ काम करने के लिए, क्या इसे app.module.ts या app.component.ts में प्रदाता के रूप में घोषित किया जाना चाहिए?
user1767316

प्रत्येक सेवा को app.module.ts में ही घोषित करते हुए, मेरे लिए काम किया।
user1767316

142

अद्यतन (कोणीय 6 +)

एकल सेवा बनाने का अनुशंसित तरीका बदल गया है। अब @Injectableसेवा में डेकोरेटर को यह निर्दिष्ट करने की सिफारिश की जाती है कि इसे 'रूट' में प्रदान किया जाना चाहिए। यह मेरे लिए बहुत मायने रखता है और अब आपके मॉड्यूल में सभी प्रदान की गई सेवाओं को सूचीबद्ध करने की कोई आवश्यकता नहीं है। आप बस सेवाओं को आयात करते हैं जब आपको उनकी आवश्यकता होती है और वे स्वयं को उचित स्थान पर पंजीकृत करते हैं। आप एक मॉड्यूल भी निर्दिष्ट कर सकते हैं, इसलिए यह केवल तब प्रदान किया जाएगा जब मॉड्यूल आयात किया गया हो।

@Injectable({
  providedIn: 'root',
})
export class ApiService {
}

अद्यतन (कोणीय 2)

NgModule के साथ, अब ऐसा करने का तरीका मुझे लगता है कि इसमें आपकी सेवा कक्षा के साथ एक 'CoreModule' बनाना है, और मॉड्यूल के प्रदाताओं में सेवा को सूचीबद्ध करना है। फिर आप अपने मुख्य ऐप मॉड्यूल में मुख्य मॉड्यूल को आयात करते हैं जो कि किसी भी बच्चे को अपने निर्माणकर्ताओं में उस कक्षा का अनुरोध करने के लिए एक उदाहरण प्रदान करेगा:

CoreModule.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ApiService } from './api.service';

@NgModule({
    imports: [
        CommonModule
    ],
    exports: [ // components that we want to make available
    ],
    declarations: [ // components for use in THIS module
    ],
    providers: [ // singleton services
        ApiService,
    ]
})
export class CoreModule { }

AppModule.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';

@NgModule({
    declarations: [ AppComponent ],
    imports: [
        CommonModule,
        CoreModule // will provide ApiService
    ],
    providers: [],
    bootstrap: [ AppComponent ]
})
export class AppModule { }

मूल उत्तर

यदि आप एक प्रदाता bootstrap()को सूचीबद्ध करते हैं, तो आपको उन्हें अपने घटक डेकोरेटर में सूचीबद्ध करने की आवश्यकता नहीं है:

import { ApiService } from '../core/api-service';

@Component({
    selector: 'main-app',
    templateUrl: '/views/main-app.html',
    // DO NOT LIST PROVIDERS HERE IF THEY ARE IN bootstrap()!
    // (unless you want a new instance)
    //providers: [ApiService]
})
export class MainAppComponent {
    constructor(private api: ApiService) {}
}

वास्तव में 'प्रोवाइडर्स' में आपकी कक्षा को सूचीबद्ध करने से इसका एक नया उदाहरण बनता है, अगर कोई अभिभावक घटक पहले से ही इसे सूचीबद्ध करता है तो बच्चों को इसकी आवश्यकता नहीं है, और यदि वे ऐसा करते हैं तो उन्हें एक नया उदाहरण मिलेगा।


1
अब (जनवरी 2017) के अनुसार, आप [providers]अपनी मॉड्यूल फ़ाइल में सेवा को सूचीबद्ध करेंगे , न कि bootstrap()सही में?
जेसन स्वेट

5
क्यों नहीं डाल ApiServiceमें AppModuleहै providers, और इस तरह के लिए आवश्यकता से बचने के CoreModule? (यह निश्चित नहीं है कि यह @JasonSwett क्या सुझाव दे रहा है।)
Jan Aagard

1
@JasonGoemaat क्या आप उदाहरण जोड़ सकते हैं कि आप इसे घटक में कैसे उपयोग करते हैं? हम ApiServiceशीर्ष पर आयात कर सकते हैं, लेकिन फिर सभी को कोरमोडुले के प्रदाताओं के सरणी में डालने के लिए परेशान क्यों करते हैं और फिर उस ऐप्पोडुले में एक आयात करते हैं ... यह मेरे लिए क्लिक नहीं किया, फिर भी।
होगन

इसलिए, मॉड्यूल प्रदाता पर सेवा डालने से उस मॉड्यूल के लिए एक सिंगलटन मिलेगा। और घटक प्रदाताओं पर सेवा डालने से घटक के प्रत्येक उदाहरण के लिए एक नया उदाहरण बन जाएगा? क्या वह सही है?
ब्रूएलएम

@BrunoLM मैंने यह दिखाने के लिए एक परीक्षण ऐप बनाया कि क्या हो रहा है। दिलचस्प है कि भले ही TestServiceकोर और ऐप दोनों मॉड्यूल में निर्दिष्ट किया गया है, उदाहरणों को मॉड्यूल के लिए नहीं बनाया गया है क्योंकि यह घटक द्वारा प्रदान किया जाता है इसलिए कोणीय पेड़ कभी भी उच्चतर नहीं होता है। इसलिए यदि आप अपने मॉड्यूल में एक सेवा प्रदान करते हैं और इसका उपयोग कभी नहीं करते हैं, तो एक उदाहरण नहीं लगता है।
जेसन गोएमाट

24

मुझे पता है कि कोइलियर ने कहा कि पदानुक्रमित इंजेक्टर हैं जैसे थियरी ने कहा।

लेकिन मेरे पास एक और विकल्प है यदि आप वास्तव में एक उपयोग-मामला पाते हैं, जहाँ आप वास्तव में इसे अभिभावक पर इंजेक्ट नहीं करना चाहते हैं।

हम सेवा का एक उदाहरण बनाकर इसे प्राप्त कर सकते हैं, और हमेशा इसे वापस कर सकते हैं।

import { provide, Injectable } from '@angular/core';
import { Http } from '@angular/core'; //Dummy example of dependencies

@Injectable()
export class YourService {
  private static instance: YourService = null;

  // Return the instance of the service
  public static getInstance(http: Http): YourService {
    if (YourService.instance === null) {
       YourService.instance = new YourService(http);
    }
    return YourService.instance;
  }

  constructor(private http: Http) {}
}

export const YOUR_SERVICE_PROVIDER = [
  provide(YourService, {
    deps: [Http],
    useFactory: (http: Http): YourService => {
      return YourService.getInstance(http);
    }
  })
];

और फिर अपने घटक पर आप अपने कस्टम प्रदान विधि का उपयोग करते हैं।

@Component({
  providers: [YOUR_SERVICE_PROVIDER]
})

और आपके पास पदानुक्रमित इंजेक्टरों के आधार पर एक सिंगलटन सेवा होनी चाहिए।

मैं यह नहीं कह रहा हूं कि यह एक बेहतर तरीका है, अगर किसी को कोई समस्या है जहां पदानुक्रमित इंजेक्टर संभव नहीं है तो बस यही है।


1
चाहिए SHARE_SERVICE_PROVIDERहोना YOUR_SERVICE_PROVIDERघटक में? इसके अलावा, मैं यह मान रहा हूं कि सेवा फ़ाइल को सामान्य की तरह आयात करना आवश्यक है और निर्माता के पास अभी भी 'YourService' प्रकार का पैरामीटर होगा, है ना? मुझे यह पसंद है मुझे लगता है, आपको एक सिंगलटन की गारंटी देने की अनुमति है और यह सुनिश्चित करने की आवश्यकता नहीं है कि सेवा पदानुक्रम प्रदान की गई है। यह एकल घटक providersप्रदाता के बजाय सेवा को सूचीबद्ध करके व्यक्तिगत घटकों को अपनी प्रति प्राप्त करने की अनुमति देता है , है ना?
जेसन गोएमाट

@JasonGoemaat आप सही हैं। संपादित किया है कि। वास्तव में, आप इसे ठीक उसी तरह से करते हैं जैसे कि निर्माता और उस घटक के प्रदाताओं पर जो आप जोड़ते हैं YOUR_SERVICE_PROVIDER। हां, सभी घटकों को केवल प्रदाताओं में जोड़कर एक ही उदाहरण मिलेगा।
जोएल अल्मेडा

इस बिंदु पर एक डेवलपर इसका उपयोग करता है, उन्हें थैम्फेल से पूछना चाहिए "अगर मैं इस स्थिति के लिए कोणीय प्रावधान प्रदान करता हूं, तो मैं भी कोणीय का उपयोग क्यों कर रहा हूं?" सेवा स्तर पर सेवा प्रदान करना कोणीय के संदर्भ में हर स्थिति के लिए पर्याप्त होना चाहिए।
RyNo

1
+1 हालांकि यह सिंगलटन सेवाओं को बनाने का एक तरीका है, यह बहुत अच्छी तरह से मल्टीटन सेवा बनाने के एक तरीके के रूप में कार्य करता है, जो instanceसंपत्ति को उदाहरणों के प्रमुख-मूल्य मानचित्र में बदल देता है
Precastic

1
@RyNo मैं एक ऐसे ऐप की कल्पना कर सकता हूं जिसमें हर रूट के लिए एक सेवा की आवश्यकता नहीं है, या एक पुन: प्रयोज्य मॉड्यूल है जो एक स्थिर उदाहरण चाहता है और किसी भी अन्य मॉड्यूल के साथ उसी उदाहरण का उपयोग करना चाहता है जो इसका उपयोग करता है। हो सकता है कि कुछ ऐसा हो जो सर्वर से वेब सॉकेट कनेक्शन बनाता है और संदेशों को संसाधित करता है। हो सकता है कि ऐप में कुछ ही रूट इसका इस्तेमाल करना चाहते हों, इसलिए जब सर्विस की जरूरत न हो तो सर्विस इंस्टेंस और वेब सॉकेट कनेक्शन बनाने की जरूरत नहीं पड़ेगी। आप इसके आस-पास प्रोग्राम कर सकते हैं कि हर जगह इसका उपयोग करने के लिए घटकों की 'इनिट' सेवा हो, लेकिन ऑन डिमांड सिंगलनेट उपयोगी होगा।
जेसन गोएमाट

16

सिंटेक्स को बदल दिया गया है। इस लिंक को देखें

एक इंजेक्टर के दायरे में निर्भरता एकल हैं। नीचे दिए गए उदाहरण में, एक एकल HeroService उदाहरण HeroComponent और उसके HeroListComponent बच्चों के बीच साझा किया गया है।

चरण 1. @ सज्जाकार डेकोरेटर के साथ सिंगलटन क्लास बनाएं

@Injectable()
export class HeroService {
  getHeroes() { return HEROES;  }
}

चरण 2. कंस्ट्रक्टर में इंजेक्ट करें

export class HeroListComponent { 
  constructor(heroService: HeroService) {
    this.heroes = heroService.getHeroes();
  }

चरण 3. रजिस्टर प्रदाता

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    routing,
    HttpModule,
    JsonpModule
  ],
  declarations: [
    AppComponent,
    HeroesComponent,
    routedComponents
  ],
  providers: [
    HeroService
  ],
  bootstrap: [
    AppComponent
  ]
})
export class AppModule { }

क्या होगा यदि मेरी Injectableकक्षा एक सेवा नहीं है और सिर्फ staticवैश्विक उपयोग के लिए तार हैं?
सैयद अली ताकी

2
इस प्रदाता की तरह: [{प्रदान करें: 'API_URL', useValue: ' coolapi.com '}]
व्हिशर

7

@Injectableसेवा में डेकोरेटर जोड़ना , और इसे रूट मॉड्यूल में एक प्रदाता के रूप में पंजीकृत करना इसे एक सिंगलटन बना देगा।


अगर मैं इसे समझ रहा हूं तो बस मुझे बताएं। अगर मैंने वही किया जो आपने कहा, ठीक है, यह एक सिंगलटन होगा। अगर, इसके अलावा, सेवा किसी अन्य मॉड्यूल में भी प्रदाता है, तो यह अब एक सिंगलटन नहीं होगा, है ना? पदानुक्रम के कारण।
हिंगिंगर

1
और पेजों के @Component डेकोरेटर में प्रदाता को पंजीकृत न करें।
लॉरा

@Laura। क्या मैं अभी भी इसे उन घटकों में आयात करता हूं जो वास्तव में सेवा का उपयोग करते हैं?
मार्क

@ मर्क हां, आपको इसे आयात करने की आवश्यकता है, और फिर आपको केवल इसे constructorइस तरह से घोषित करने की आवश्यकता है :import { SomeService } from '../../services/some/some'; @Component({ selector: 'page-selector', templateUrl: 'page.html', }) export class SomePage { constructor( public someService: SomeService ) { }
लौरा

6

यह मेरे लिए अच्छा काम कर रहा है

@Injectable()
export class MyStaticService {
  static instance: MyStaticService;

  constructor() {
    return MyStaticService.instance = MyStaticService.instance || this;
  }
}

8
मैं इसे Angular2 एंटी-पैटर्न कहूंगा। सेवा को सही ढंग से प्रदान करें और Angular2 हमेशा एक ही उदाहरण को इंजेक्ट करेगा। यह भी देखें stackoverflow.com/questions/12755539/…
Günter Zöchbauer

3
@ गुंटर ज़ोचबॉयर, कृपया "सही ढंग से सेवा प्रदान करें और Angular2 हमेशा एक ही उदाहरण है।" ? क्योंकि यह अस्पष्ट है और मुझे googling द्वारा कोई उपयोगी जानकारी नहीं मिली।
nowiko

मैंने अभी-अभी यह उत्तर पोस्ट किया है जो आपके प्रश्न के साथ मदद कर सकता है stackoverflow.com/a/38781447/217408 (वहां लिंक भी देखें)
Günter Zöchbauer

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

मैंने इस पैटर्न का उपयोग यह पता लगाने के लिए किया था कि मैं जिस समस्या का सामना कर रहा था, वह सेवा के कारण सिंगलटन नहीं होने के कारण था
hr-tis

5

यहां एंगुलर वर्जन 2.3 के साथ काम करने का उदाहरण दिया गया है। बस सेवा के निर्माता को इस निर्माता (निजी _userService: UserService) की तरह से स्टैंड कॉल करें। और यह ऐप के लिए एक सिंगलटन बनाएगा।

user.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Subject }    from 'rxjs/Subject';
import { User } from '../object/user';


@Injectable()
export class UserService {
    private userChangedSource;
    public observableEvents;
    loggedUser:User;

    constructor() {
       this.userChangedSource = new Subject<any>();
       this.observableEvents = this.userChangedSource.asObservable();
    }

    userLoggedIn(user:User) {
        this.loggedUser = user;
        this.userChangedSource.next(user);
    }

    ...
}

app.component.ts

import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { UserService } from '../service/user.service';
import { User } from '../object/user';

@Component({
    selector: 'myApp',
    templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
    loggedUser:User;

    constructor(private _userService:UserService) { 
        this._userService.observableEvents.subscribe(user => {
                this.loggedUser = user;
                console.log("event triggered");
        });
    }
    ...
}

4

A singleton serviceएक ऐसी सेवा है जिसके लिए एक ऐप में केवल एक उदाहरण मौजूद है।

कर रहे हैं (2) तरीके आपके आवेदन के लिए एक सिंगलटन सेवा प्रदान करते हैं।

  1. providedInसंपत्ति का उपयोग करें , या

  2. AppModuleआवेदन में सीधे मॉड्यूल प्रदान करें

उपलब्ध कराई गई का उपयोग करना

एंगुलर 6.0 के साथ शुरुआत करते हुए, एक सिंगलटन सेवा बनाने का पसंदीदा तरीका providedInसेवा के @Injectable()डेकोरेटर पर रूट करना है । यह कोणीय को एप्लिकेशन रूट में सेवा प्रदान करने के लिए कहता है।

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

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

NgModule प्रदाताओं सरणी

6.0 से पहले कोणीय संस्करणों के साथ निर्मित ऐप में, सेवाओं को पंजीकृत किया गया है NgModule प्रदाताओं सरणियों निम्नानुसार हैं:

@NgModule({
  ...
  providers: [UserService],
  ...
})

यदि यह NgModuleरूट होता AppModule, तो UserService एक सिंगलटन होता और पूरे ऐप में उपलब्ध होता। यद्यपि आप इसे इस तरह से कोडित कर सकते हैं, सेवा पर डेकोरेटर की providedInसंपत्ति का उपयोग करना @Injectable()ही बेहतर है क्योंकि यह आपकी सेवा को पेड़-शाक योग्य बनाता है।


3

आप useValueप्रदाताओं में उपयोग कर सकते हैं

import { MyService } from './my.service';

@NgModule({
...
  providers: [ { provide: MyService, useValue: new MyService() } ],
...
})

5
useValueसिंगलटन से संबंधित नहीं है। Usevalue सिर्फ एक Type( useClass) के बजाय एक मान पारित करने के लिए है जो DI newपर कॉल करता है या useFactoryजहां एक फ़ंक्शन पारित किया जाता है जो DI द्वारा बुलाए जाने पर मान लौटाता है। कोणीय डीआई प्रति प्रदाता एक ही उदाहरण स्वचालित रूप से रखता है। केवल इसे एक बार प्रदान करें और आपके पास एक सिंगलटन है। क्षमा करें, मुझे नीचे जाना है क्योंकि यह सिर्फ अमान्य जानकारी है: - /
गुंटर ज़ोचाउर

3

कोणीय @ 6 से, आप कर सकते हैं providedInएक में Injectable

@Injectable({
  providedIn: 'root'
})
export class UserService {

}

यहां डॉक्स की जांच करें

सेवा को सिंगुलर बनाने के दो तरीके हैं:

  1. घोषणा करें कि सेवा को एप्लिकेशन रूट में प्रदान किया जाना चाहिए।
  2. AppModule में या केवल AppModule द्वारा आयातित मॉड्यूल में सेवा शामिल करें।

एंगुलर 6.0 के साथ शुरुआत करते हुए, एक सिंगलटन सेवाओं को बनाने का पसंदीदा तरीका उस सेवा पर निर्दिष्ट करना है जिसे इसे एप्लिकेशन रूट में प्रदान किया जाना चाहिए। यह सेवा के @Injectable डेकोरेटर पर रूट करने के लिए प्रदान की गई सेटिंग द्वारा किया जाता है:


यह अच्छा है, लेकिन आपको चर के साथ अप्रत्याशित समस्याएं भी हो सकती हैं जो कुछ वस्तुओं की घोषणा करके हल नहीं हो सकती हैं public static
cjbarth

2

केवल app.module.ts में प्रदाता के रूप में अपनी सेवा की घोषणा करें।

इसने मेरे लिए काम किया।

providers: [Topic1Service,Topic2Service,...,TopicNService],

फिर या तो एक निर्माता निजी पैरामीटर का उपयोग कर इसे स्थापित करें:

constructor(private topicService: TopicService) { }

या यदि आपकी सेवा HTML से उपयोग की जाती है, तो -प्रोड विकल्प दावा करेगा:

Property 'topicService' is private and only accessible within class 'SomeComponent'.

अपनी सेवा के लिए एक सदस्य जोड़ें और इसे निर्माणकर्ता में प्राप्त उदाहरण से भरें:

export class SomeComponent {
  topicService: TopicService;
  constructor(private topicService: TopicService) { 
    this.topicService= topicService;
  }
}

0
  1. यदि आप आवेदन स्तर पर सेवा एकल बनाना चाहते हैं, तो आपको इसे app.module.ts में परिभाषित करना चाहिए

    प्रदाता: [MyApplicationService] (आप इसे उस मॉड्यूल विशिष्ट बनाने के लिए बाल मॉड्यूल में भी परिभाषित कर सकते हैं)

    • प्रदाता में इस सेवा को न जोड़ें जो उस घटक के लिए एक उदाहरण बनाता है जो सिंगलटन अवधारणा को तोड़ता है, बस कंस्ट्रक्टर के माध्यम से इंजेक्ट करता है।
  2. यदि आप घटक स्तर पर एकल सेवा को परिभाषित करना चाहते हैं, तो उस सेवा को app.module.ts में जोड़ें और विशिष्ट घटक के अंदर प्रदाताओं सरणी में जोड़ें जैसा कि नीचे दिए गए स्निपेट में दिखाया गया है।

    @Component ({चयनकर्ता: 'app-root', templateUrl:'/test.component.html ', styleUrls: [' ./test.component.scss '], प्रदाता: [TestMinService]})

  3. कोणीय 6 आवेदन स्तर पर सेवा को जोड़ने का नया तरीका प्रदान करता है। AppModule में प्रदाताओं [] सरणी में एक सेवा वर्ग जोड़ने के बजाय, आप @ () में निम्नलिखित विन्यास सेट कर सकते हैं:

    @ इंजेक्शन ({प्रदान किया गया: 'रूट'}) निर्यात वर्ग MyService {...}

"नया सिंटैक्स" एक लाभ प्रदान करता है, हालांकि: सेवाओं को एंगुलर (पर्दे के पीछे) द्वारा आलसी लोड किया जा सकता है और अनावश्यक कोड को स्वचालित रूप से हटाया जा सकता है। इससे एक बेहतर प्रदर्शन और लोडिंग गति हो सकती है - हालांकि यह वास्तव में केवल बड़ी सेवाओं और ऐप्स के लिए सामान्य रूप से चलता है।


0

उपरोक्त उत्कृष्ट उत्तरों के अलावा, कुछ और भी हो सकता है जो गायब है यदि आपके सिंगलटन में चीजें अभी भी एक सिंगलटन के रूप में व्यवहार नहीं कर रही हैं। मैं इस मुद्दे पर भाग गया जब एक सार्वजनिक समारोह को सिंगलटन पर कॉल किया और पाया कि यह गलत चर का उपयोग कर रहा है। यह पता चलता है कि समस्या thisयह नहीं थी कि सिंगलटन में किसी भी सार्वजनिक कार्य के लिए सिंगलटन के लिए बाध्य किया जाए। यहाँ सलाह का पालन ​​करके इसे ठीक किया जा सकता है , जैसे:

@Injectable({
  providedIn: 'root',
})
export class SubscriptableService {
  public serviceRequested: Subject<ServiceArgs>;
  public onServiceRequested$: Observable<ServiceArgs>;

  constructor() {
    this.serviceRequested = new Subject<ServiceArgs>();
    this.onServiceRequested$ = this.serviceRequested.asObservable();

    // save context so the singleton pattern is respected
    this.requestService = this.requestService.bind(this);
  }

  public requestService(arg: ServiceArgs) {
    this.serviceRequested.next(arg);
  }
}

वैकल्पिक रूप से, आप public staticइसके बजाय कक्षा के सदस्यों को घोषित कर सकते हैं public, तब संदर्भ कोई मायने नहीं रखेगा, लेकिन आपको SubscriptableService.onServiceRequested$निर्भरता इंजेक्शन का उपयोग करने और उनके माध्यम से एक्सेस करने के बजाय उन्हें एक्सेस करना होगा this.subscriptableService.onServiceRequested$


0

माता-पिता और बच्चे की सेवा

मुझे एक अभिभावक सेवा और उसके बच्चे को विभिन्न उदाहरणों का उपयोग करने में परेशानी हो रही थी। एक उदाहरण का उपयोग करने के लिए बाध्य करने के लिए, आप अपने ऐप मॉड्यूल प्रदाताओं में माता-पिता को बच्चे के संदर्भ में उर्फ ​​कर सकते हैं। माता-पिता बच्चे के गुणों का उपयोग नहीं कर पाएंगे, लेकिन दोनों सेवाओं के लिए एक ही उदाहरण का उपयोग किया जाएगा। https://angular.io/guide/dependency-injection-providers#aliased-class-providers

app.module.ts

providers: [
  ChildService,
  // Alias ParentService w/ reference to ChildService
  { provide: ParentService, useExisting: ChildService}
]

आपके ऐप मॉड्यूल दायरे के बाहर के घटकों द्वारा उपयोग की जाने वाली सेवाएँ

एक घटक और एक सेवा से मिलकर एक पुस्तकालय बनाते समय, मैं एक ऐसे मुद्दे पर भाग गया, जहां दो उदाहरण बनाए जाएंगे। एक मेरी कोणीय परियोजना द्वारा और एक मेरे पुस्तकालय के अंदर घटक द्वारा। जोड़:

मेरी-outside.component.ts

@Component({...})
export class MyOutsideComponent {
  @Input() serviceInstance: MyOutsideService;
  ...
}

मेरी-inside.component.ts

  constructor(public myService: MyOutsideService) { }

मेरी-inside.component.hmtl

<app-my-outside [serviceInstance]="myService"></app-my-outside>

क्या आप अपने खुद के सवाल का जवाब देना चाहते थे? यदि हां, तो आप प्रश्न के पोस्ट होने के बाद, उत्तर को स्टैकऑवरफ्लो पर एक औपचारिक उत्तर में अलग कर सकते हैं, इसे कट / पेस्ट करके उत्तर क्षेत्र में भेज सकते हैं।
ryanwebjackson
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.