Angular + rxjs:没有Subscription提供商

时间:2017-09-28 12:17:59

标签: angular typescript rxjs

我正在尝试以角度形式实现服务组件通信,当服务保存一个值并且组件订阅更改时。我正在使用rxjs订阅,但我正在

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

以下是我在服务中所做的事情:

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();
 }
}

并在组件中:

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();
  }
}

组件和服务捆绑到模块中,稍后将其注入另一个模块。

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 {}

显然,我在这里做错了什么

5 个答案:

答案 0 :(得分:3)

只需从构造函数中删除private subscription: Subscription并将其放在类的属性中即可。

答案 1 :(得分:1)

在您的服务中,您可以首先更改rxjs导入,如下所示:

// Imports...
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin'

// ...

  ionViewDidLoad() {

    // Show the loader
    this.loadingService.showLoader(this.constants.MSG_LOADING);

    Observable.forkJoin([
        this.remedyProvider.getSummaryByDate(),
        this.remedyProvider.getHeatmap()
    ]).subscribe(
        response => {
            let summaryResponse = response[0];
            let heatmapResponse = response[1];

            // Do something with the responses...
            // ...
        }, 
        error => {
            // TODO: handle the error!
            console.log(`Backend returned error was: ${error}`);
        },
        () => {
            console.log('Both request are done');

            // Hide the loader
            this.loadingService.hideLoader();
        });
  }

从'rxjs / Observable'导入{Observable}时我遇到了问题。现在我对此很谨慎:P! (我应该进一步深入了解场景背后的真实情况。)

然后,正如Lyubimov Roman在上面的评论中所说,你不应该通过构造函数导入rxjs subscription 。我不明白你对Lyubimov评论的回答。您能否请您提供您提及的示例,以便让我们弄清楚目的是什么?

如果您需要在组件中使用订阅对象,只需将其导入如下:

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

答案 2 :(得分:1)

从构造函数中删除它,并在外部声明它。

private _Subscription: Subscription;

  constructor() {
  }

答案 3 :(得分:0)

即使我是新手,也遇到过多次此问题,也无法理解问题所在。因此,首先要确保已正确将导入声明为import { Observable, Subscription } from 'rxjs';

对我来说,错误是空注入错误。没有订阅服务提供商

最初,我开始在构造函数中将 Subscription 声明为:

constructor(){private activatedsubscription:Subscription}

这是行不通的,因为我后来意识到它之所以为Null注入,是因为它是在构造函数内部声明的,因此应在构造函数外部声明为属性,或者在Class内部全局声明为:

export class Component implements OnInit{
activatedsubscription:Subscription
}

注意:请确保在销毁组件时通过调用 OnDestroy 从订阅中取消订阅。否则,您将内存泄漏

答案 4 :(得分:-1)

我开始时确保您将导入正确声明为

import { Subscription } from 'rxjs'

然后我用它作为

public subscription : Subscription = new Subscription();