有关此Angular + ngRx(效果)的建议 - websocket事件怎么样?

Jem*_*Jem 7 redux ngrx ngrx-effects angular ngrx-store

所以我通过构建以下沙箱来试验ngrx&ngrx/effects:

https://stackblitz.com/edit/ngrx-vanilla

快速介绍:

  • 它在app/store中有一个根存储
  • 它在app/features中延迟加载了两个模块
  • 它在app/commons中有单例服务

三页:

  • 行动项目:路由到此页面会触发随机生成三个愚蠢的公司行动项目
  • 用户:具有路由器支持的基本主> detail redux实现
  • 会议:提出问题的地方,点击"开始会议",见证相关的意见交流.

问题和背景:

  • 我理解redux中的所有数据更新都是通过操作实现的
  • "效果"库用于处理异步事件,以便根据第三方事件和异步调用发送新操作.
  • app/common/meeting/service模仿例如websocket或firebase实时数据库推送更新的行为.

收到更新后(在app/store/effects/meeting.effects.ts中说明),将调度新操作.

最后,问题是:让一个共同的服务了解商店是一种干净的做法吗?将一个监听器注册到websocket/firebase实时数据库以便在推送数据时调度操作的最佳位置在哪里?

在这里,我做了一个效果(meeting.effects)对meetingActions.START_MEETING操作类型做出反应,每当推送数据时,都会向商店发送更新订单,但由于我提出的一系列原因,这感觉不对:

  • 难以单独进行单元测试(需要比自身更多的上下文)
  • 在"停止会议"操作的情况下,此方法需要存储订阅(或?)以停止订阅.在我的方法中,无法控制在荒野中创造的可观察物.

这些案件通常如何处理?

Abd*_*eem 6

假设websocket正在发出不同类型的事件,则将每个事件映射到websocket服务中的不同操作,例如

@Injectable()
class WebsocketService{
    private socket$:Observable<Action>
    getActions():Observable<Action>{
        if(!this.socket$) {
           this.socket$ = Observable.webSocket(url).pipe(
               map(functionToMapActions)
            ,shareReplay(1)
           );
        }
        return this.socket$;
    }
}
Run Code Online (Sandbox Code Playgroud)

其中functionToMapActions将webSocket事件映射为动作,建议shareReplay在最后添加操作符,以便我们仅读取一次webSocket。

the Observable.webSocket connects to webSocket , and emits events as they arrive

webSocket connection will be established when you suscribe to webService.getActions()

You can subscribe to websocket actions in @Effects initialization see here

@Effect()
init$ = this.websocketService.getActions();
Run Code Online (Sandbox Code Playgroud)

this will emit all actions as soon as your app starts (if effect in in root module) or your module is loaded if it is in lazy loaded module;

Or if you are interrested in limited set of actions you can do like this

@Effect()
init$ = this.websocketService.getActions().pipe(filter(filterNeededActionsHere));
Run Code Online (Sandbox Code Playgroud)

you can also start listening to actions only after perticular event like this

@Effect()
init$ = this.actions$.pipe(
          ofType('Event which marks start')
          ,swichMapTo(this.websocketService.getActions())
     );
Run Code Online (Sandbox Code Playgroud)

like previous example you can also filter out action here sane as before

hope this answers your question