2017-09-28 1 views
0

J'essaie de mettre en œuvre une communication de service-composant en mode angulaire, lorsque le service contient une valeur et que le composant s'y abonne. J'utilise Abonnement rxjs, mais je reçoisAngular + rxjs: Aucun fournisseur d'abonnement

Uncaught (in promise): Error: No provider for Subscription! 

Voici ce que je fais dans un service:

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs'; 
import { Subject } from 'rxjs/Subject'; 

@Injectable() 
export class PracticeContextService { 
    practice: Subject<any> = new Subject<any>(); 
    public practiceSelected$ = this.practice.asObservable(); 

setPractice(providerId: string) { 
    this.practice.next({ providerId: providerId }); 
} 

getPractice(): Observable<any> { 
    return this.practice.asObservable(); 
} 
} 

et dans le composant:

import { Component, OnDestroy, OnInit } from '@angular/core'; 
import { Subscription } from 'rxjs/Subscription'; 
import { PracticeContextService } from '../practice-context.service'; 

@Component({ 
    selector : 'practice-context-selector', 
    templateUrl : './practice-context-selector.component.html', 
    styleUrls : ['./practice-context-selector.component.css'] 
}) 

export class PracticeContextSelectorComponent implements OnInit, OnDestroy { 

    practice: string; 

    constructor(private context: PracticeContextService, 
      private subscription: Subscription) {} 

    ngOnInit() { 
    this.subscription = this.context.practiceSelected$.subscribe(
     practice => { 
     this.practice = practice; 
     }); 
    } 

    ngOnDestroy() { 
    this.subscription.unsubscribe(); 
    } 
} 

Component et le service sont regroupés dans le module, qui est ensuite injecté dans un autre module.

import { NgModule }   from '@angular/core'; 
import { CommonModule }  from '@angular/common'; 

import { PracticeContextSelectorComponent } from './practice-context-selector/practice-context-selector.component'; 
import { PracticeContextService } from './practice-context.service'; 

@NgModule({ 
    imports : [ 
    CommonModule 
    ], 
    declarations : [ 
    PracticeContextSelectorComponent 
    ], 
    providers : [ 
    PracticeContextService, 
    ], 
    exports: [ 
    PracticeContextSelectorComponent 
    ] 
}) 

export class PracticeContextModule {} 

Apparemment, je fais quelque chose de mal ici

+0

Si vous avez un paramètre constructeur dans une classe instanciée par angulaires DI, alors il doit y avoir une fournisseur correspondant. Quel est le but de ce paramètre dans 'constructeur (contexte privé: PracticeContextService, abonnement privé: Abonnement)'? –

+1

L'abonnement n'est pas pour DI, importez-le comme 'import {Subscription} de 'rxjs/Subscription';'. –

+0

@ lyubimov-roman Je suis en train de faire cette importation dans un composant. Si je ne dois pas câbler cette dépendance à un composant dans le constructeur, quelle est la bonne façon d'utiliser? Je demande parce que j'ai trouvé une poignée d'exemples en utilisant cette approche, mais cela ne semble pas fonctionner pour moi. – vitalym

Répondre

1

Dans votre service, vous pourriez d'abord des importations de tous changement comme celui-ci:

import { Observable, Subscription } from 'rxjs/Rx'; 

j'avais déjà un problème lorsque importer {Observable} à partir de 'rxjs/Observable'. Maintenant, je suis prudent avec ceci: P! (Je devrais peut-être creuser plus loin pour savoir ce qui se passe vraiment derrière la scène.)

Ensuite, comme déjà dit Lioubimov romain dans son commentaire ci-dessus, vous ne devriez pas importer rxjs abonnement par le constructeur. Je ne comprends pas votre réponse au commentaire de Lyubimov. Pourriez-vous s'il vous plaît nous fournir les exemples que vous mentionnez afin de nous permettre de comprendre ce qui est prévu?

Si vous avez besoin d'utiliser un objet de souscription dans votre composant, il suffit d'importer comme ceci:

import { Subscription } from 'rxjs/Rx'; 
+0

Mais mieux vaut l'importer séparément si vous ne voulez pas importer le module entier. –

+0

En effet, j'ai finalement réalisé que je peux le déclarer dans la partie où je déclare les types, comme abonnement: Abonnement; au lieu du constructeur. Merci! – vitalym