【问题标题】:Observable BehaviorSubject Service - Singleton and providersObservable BehaviorSubject 服务 - 单例和提供者
【发布时间】:2017-01-25 17:05:08
【问题描述】:

我有一个简单的组件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);
  }
}

这里没什么特别的,只是一个默认设置为false的BehaviorSubject,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();
  }
}

在初始化期间,组件订阅主题以获得默认值并将其设置为isDisplayshowProgress 仅用于在我的模板中试用。

<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 中的提供者?)

【问题讨论】:

  • 是的,这可能是一个原因。在 NgModule 中声明它并从两个组件中删除。
  • 天哪!你是对的,这就是原因。我从提供者的组件中删除了ProgressBarService,然后将其添加到app.module.js。现在他们都共享同一个实例并且它可以工作!嗯,谢谢楼主。今晚我才明白一件事:)
  • 太棒了!!!那就享受 Angular2 吧!

标签: angular service singleton behaviorsubject angular2-providers


【解决方案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 { }

组件现在共享同一个实例,进度条显示良好。

【讨论】:

    猜你喜欢
    • 2014-04-20
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 2013-02-06
    • 2017-01-11
    • 2019-05-29
    • 1970-01-01
    相关资源
    最近更新 更多