2017-06-07 54 views
0

我在想如果我可以解决没有主题的以下方案。我有两个组件:第一个组件创建一个英雄,另一个组件显示一个英雄。这些组件通过服务进行通信。目前,我有以下解决方案:Angular 2通过服务进行通信而不使用主题

英雄创造

@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$ 
    } 
} 

目标是仅使用普通Observables实现相同的功能而不使用主题。

+1

既然你添加新的英雄'这是基于一些用户操作addHero()'我不认为你能避免使用课程。 – martin

+0

你能否说出你为什么要这样做?因为事情是,你不能简单地发送数据在任何observable上 - 在技术上我会猜测其他方式,但我不会推荐这些。 - 如果你不想坚持纯rxjs看看ngrx – olsn

+0

理论上你可以使用'Observable.fromEvent().map()'而不是Angular的'(click)',但这会让事情变得更加复杂。 – martin

回答

0

这是一个主题的用例。

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

hero$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作为一个二传手,暴露一个主题作为公共财产打破封装。为了维护封装,可以只露出hero$观察到的,而不是:

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