Angular 2通过服务进行通信而不使用主题

时间:2017-06-07 07:54:39

标签: angular rxjs reactive

我想知道如果没有主题我是否可以解决以下场景。我有两个组件:第一个组件创建一个英雄,另一个组件显示一个英雄。这些组件通过服务进行通信。目前我有以下解决方案:

英雄创作

@Component({
  selector: 'hero-creation',
  ....
})
export class HeroCreation{

  constructor(private heroSercice: HeroService){
  }

  onClick(){
     this.heroSercice.addHero();
  }
}

英雄服务

@Injectable()
export class HeroService {
public hero$: Subject<string> = new Subject<string>();

  constructor() {
  }

  public addHero(hero: string): void {
    this.hero$.next(hero);
  }
}

英雄显示

@Component({
selector: 'hero-display',
....
})
export class HeroDisplay{

  constructor(private heroSercice: HeroService){
    //Use async pipe in template to display the hero
    this.heros$ = this.heroSercice.hero$
  }
}

目标是在不使用主题的情况下使用普通的Observable实现相同的功能。

1 个答案:

答案 0 :(得分:0)

这是主题的用例。

  

Subject类继承了Observable和Observer,因为它既是观察者又是可观察者。

创建hero$ observable后,应以某种方式向其添加新值。它们应该通过观​​察者加入。没有主题,观察者必须手动曝光才能到达它:

protected _heroObserver: Observer<string>;
public hero$: Observable<string> = Observable.create<string>(observer => {
    this._heroObserver = observer;
});
...
public addHero(hero: string): void {
    this._heroObserver.next(hero);
}

这正是受试者应该做的事情。由于addHero充当setter,因此将主题公开为公共属性会破坏封装。为了保留封装,可以仅公开hero$ observable:

protected _heroSubject: Subject<string> = new Subject<string>();
public hero$: Observable<string> = this._heroSubject.asObservable();
...
public addHero(hero: string): void {
    this._heroSubject.next(hero);
}