Observable BehaviorSubject Service - Синглтон и провайдеры

У меня есть простой компонент progressBar для того, чтобы отобразить (или нет) индикатор выполнения. И простой наблюдаемый сервис.

Вот услуга:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable() 
export class ProgressBarService {
  subject = new BehaviorSubject<any>(false);
  changes = this.subject
              .asObservable()
              .do(changes => console.log('new state', changes)); 

  constructor(private http: Http) {
  }
  show() {
    this.subject.next(true);
  }
  hide() {
    this.subject.next(false);
  }
}

Ничего особенного, просто BehaviorSubject, который установлен по умолчанию с false, hide/show используется для изменения значения с .next(),

Компонент выглядит так:

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { ProgressBarService } from './progressbar.service';

@Component({
  selector: 'app-progressbar',
  templateUrl: './progressbar.component.html',
  styleUrls: ['./progressbar.component.scss'],
  providers:[ProgressBarService]
})

export class ProgressbarComponent implements OnInit {

  isDisplay : boolean;

  constructor(private $progressbar : ProgressBarService) { }

  ngOnInit() {
    this.$progressbar
      .changes
      .subscribe((display : boolean) => this.isDisplay = display);
  }

  showProgress(){
    (this.isDisplay)
      ? this.$progressbar.hide()
      : this.$progressbar.show();
  }
}

Во время инициализации компонент подписывается на тему, чтобы получить значение по умолчанию и установить его в isDisplay,showProgress используется только, чтобы попробовать это в моем шаблоне.

<md-progress-bar mode="indeterminate" color="accent" *ngIf="isDisplay"></md-progress-bar>

<button type="submit" md-raised-button color="primary" (click)="showProgress()">Show/hide progressBar</button>

И это прекрасно работает, когда служба используется внутри компонента.

Но когда я пытаюсь вызвать этот сервис внутри другого компонента, он не работает.

Пример: мой другой компонент с именем profileComponent

import { ProgressBarService } from ../progressbar/progressbar.service';

@Component({
  selector: 'profiles',
  templateUrl: 'profiles.component.html',
  providers: [ProgressBarService]
})

export class ProfilesComponent implements OnInit {

  toto :boolean = false;

  constructor(private $progressbar : ProgressBarService) {}

  ngOnInit() {}

  showProgress() {
    if(this.toto) {
      this.$progressbar.hide();
      this.toto = false; 
    } else {
      this.$progressbar.show();
      this.toto = true;
    }
  }
}

Я думаю, это потому, что два компонента не используют один и тот же экземпляр службы, но я не могу найти способ сделать это. (Может быть, провайдеры в @NgModule?)

1 ответ

Благодаря @micronyks, вот решение.

Для каждого компонента я добавляю сервис в компонент провайдера. В результате компоненты создают новый экземпляр службы.

Чтобы решить эту проблему, я удалил сервис из провайдеров каждого компонента, а затем предоставил его основному модулю.

import { ProgressBarService } from './progressbar/progressbar.service';

@NgModule({
  imports: [
    CommonModule,
    BrowserModule,
    HttpModule,
    AppRoutingModule,
    HomeModule,
    MaterialModule.forRoot()
  ],
  declarations: [AppComponent, ProgressbarComponent],
  providers: [ProgressBarService],
  bootstrap: [AppComponent],
})
export class AppModule { }

Компоненты теперь совместно используют один и тот же экземпляр, и индикатор выполнения хорошо отображается.

Другие вопросы по тегам