简体   繁体   中英

Angular 6 - Using channels in Rxjs Observable

The following Angular 6 service can be used to send/receive messages to/from other services/components (note that getMsg returns an 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();
    }
}

Now, what I need is to allow the sender/receiver to use channels, similar to AngularJS event names in $emit/broadcast. sendMsg signature would be as follows:

sendMsg(channel: string, message: any)

and to receive a message, the receiver will have to subscribe the Observable using a channel name. Is this possible?

Note: I don't want to use filter in the subscription as it would affect performance if the number of messages is large. I prefer to use an Rxjs native option.

You can still use a single subject but filter out the channel that you don't want to subscribe or send, something similar to the following approach.

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));
    }
}

Usuage

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

There is no built-in solution to this in rxjs. I'd suggest to keep your current approach, but build a wrapper arround each possible channel. Here is an example:

export class MessageChannelWrapper {
   news: string,
   warnings: string,
   alerts: string

   constructor( ){}
}


wrapper = new MessageChannelWrapper();
wrapper.news = 'this is the news'. 

This way you can extend your wrapper and add as much 'channels' as you need and directly access them by name.

The other solution is to add a Subject for each channel to the Service and subscribe to the channels you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM