【问题标题】:Angular 6 - Using channels in Rxjs ObservableAngular 6 - 在 Rxjs Observable 中使用通道
【发布时间】:2018-08-05 14:10:00
【问题描述】:

以下 Angular 6 服务可用于向/从其他服务/组件发送/接收消息(注意 getMsg 返回一个 Observable):

@Injectable({ 
    providedIn: 'root' 
})
export class MessageService {

    private subject = new Subject<any>();

    sendMsg(message: any) {
        this.subject.next(message);
    }

    getMsg(): Observable<any> {
        return this.subject.asObservable();
    }
}

现在,我需要允许发送方/接收方使用通道,类似于 $emit/broadcast 中的 AngularJS 事件名称。 sendMsg 签名如下:

sendMsg(channel: string, message: any)

为了接收消息,接收者必须使用频道名称订阅 Observable。这可能吗?

注意:我不想在订阅中使用filter,因为如果消息数量很大,它会影响性能。我更喜欢使用 Rxjs 原生选项。

【问题讨论】:

  • 你不想使用filter,因为你想要一个 RxJS 选项?我很困惑...
  • 原生选项 = 命名频道

标签: angular rxjs rxjs6


【解决方案1】:

您仍然可以使用单个主题,但过滤掉您不想订阅或发送的频道,类似于以下方法。

export class MessageService {

    private subject = new Subject<any>();

    sendMsg({channel,message: any}) {
        this.subject.next({channel,message});
    }

    getMsg(_channel): Observable<any> {
        return this.subject.asObservable().filter(({channel,res})=>(channel==_channel));
    }
}

用法

messageService.send('channel1','hello').subscribe()
messageService.getMsg('channel1').subscribe()

【讨论】:

    【解决方案2】:

    rxjs 中没有内置的解决方案。我建议保留您当前的方法,但围绕每个可能的渠道构建一个包装器。这是一个例子:

    export class MessageChannelWrapper {
       news: string,
       warnings: string,
       alerts: string
    
       constructor( ){}
    }
    
    
    wrapper = new MessageChannelWrapper();
    wrapper.news = 'this is the news'. 
    

    通过这种方式,您可以扩展包装器并根据需要添加尽可能多的“通道”,并通过名称直接访问它们。

    另一种解决方案是将每个频道的主题添加到服务并订阅您需要的频道。

    【讨论】:

      猜你喜欢
      • 2018-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      相关资源
      最近更新 更多