2

У меня есть простой компонент progressBar, чтобы отображать (или нет) индикатор выполнения. И простой наблюдаемый сервис.Observable BehaviorSubject Service - Singleton и провайдеры

Вот служба:

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> 

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

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

Пример: Мой другой компонент, называемый profilesComponent

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?)

+3

Да, это может быть причиной. объявите его в NgModule и удалите из обоих компонентов. – micronyks

+1

Holy ****! Вы правы, это причина. Я удалил «ProgressBarService» из компонентов поставщика, а затем добавил его в 'app.module.js'. Теперь они оба имеют один и тот же экземпляр, и он работает! Хорошо, спасибо, сэр. Я только что понял что-то сегодня :) – ByJC

+0

Отлично !!! наслаждайтесь Angular2 тогда! – micronyks

ответ

2

Благодаря @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 { } 

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

Смежные вопросы