Angular 2: 事件广播服务

4
我正在尝试创建事件广播服务。
以下是我想要实现的基本概念:
export enum Event {
   EVENT_A,
   EVENT_B, ...
}


@Injectable()
export class BroadcastService {

     private broadcastSubject: Subject<Event> = new Subject<Event>();

     public next(event: Event): void {
         return this.broadcastSubject.next(event);
     }

     public subscribe(event: Event, componentCall: Function): void {
         this.broadcastSubject.subscribe(
             eventValue => {
                if(event === eventValue) {
                  componentCall(); // not possible to call component's method like this
                } 
             }
        );
   }
}

我知道我不能像这样从服务中调用组件的方法。我必须以某种方式返回可观察对象并从组件中调用它。我不确定如何实现这一点。
感谢任何建议。

解决方案

感谢AngularFrance,以下是BroadcastService的解决方案:

@Injectable()
export class BroadcastService {

  private broadcastSubject: BehaviorSubject<Event> = new BehaviorSubject<Event>(0);

  public next(event: Event): void {
     return this.broadcastSubject.next(event);
  }

  public subject(event: Event): Observable<Event> {
     return this.broadcastSubject.asObservable().filter(e => e === event);
  }

}

TypeScript不支持回调函数,你不能这样做。 - Aravind
2个回答

5

您应该从BroadcastService返回可观察对象(注意,Subject是一个Observable):

@Injectable()
export class BroadcastService {

     private event: Subject<Event> = new Subject<Event>();

     public next(event: Event): void {
       return this.event.next(event);
     }

     public getEvents(event: Event): Observable<Event> {
       // DO NOT SUBSCRIBE HERE. Return the observable.
       return this.event.asObservable()
         // Only keep events matching the given `event` param
         .filter(e => e == event);
     }
}

然后在组件中订阅返回的可观察对象:

export class MyComponent {

  constructor(bcservice: BroadcastService) {
    // Subscribe here.
    bcservice.getEvents(event).subscribe(eventValue => {
      this.someMethod();
    });
  }

  someMethod() { }

}

注意:如果你只需要流中的某种特定类型的事件,那么在将它们添加到流中(在next()方法中)之前过滤掉不需要的事件可能更加优化,而不是在返回流时进行过滤。


谢谢你的回答。但是我想要实现的是,/* test eventValue */ 应该在 BroadcastService 中,否则将没有将 Subject 包装到 BroadcastService 中的意义。 - Tomas Marik
你是说你只想在特定事件发生时调用你的方法? - AngularChef
是的,我想仅订阅一个事件:subscribe(event: Event, ...)。 - Tomas Marik
那我建议你传递一个参数到 getEvents()(就像你在原始代码中所做的那样),并使用该参数来使用 .filter() 操作符过滤可观察对象。请参阅我的更新答案。 - AngularChef
这正是我正在寻找的。谢谢! - Tomas Marik

0

1
这似乎不是一个好主意:https://dev59.com/lVoV5IYBdhLWcg3wkvh1 - Tomas Marik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接