使用Methods访问Ng/Rx中不同的SignalStore

问题描述 投票:0回答:1

我已经习惯了传统的 Ng/Rx,现在正在深入研究 Signals 和 Ng/Rx SignalStore。

我知道通过 SignalStore,我们可以提供 withMethods。 然后,我们可以从注入商店的组件中调用商店上的这些方法。

假设我有一个书店和一个用户商店。 用户存储存储当前登录的用户。基本上只有当用户登录/退出时它才会改变。 书店存储书籍列表,并有一个方法为当前用户加载书籍。

下面的代码是如何设置的? 在传统的 Ng/Rx 中,我们会有一个效果,对操作做出反应,然后从用户状态获取最新值,执行请求,然后调度另一个操作。在 bookStore 中提到 userStore 对我来说感觉像是代码味道。

const BooksStore = signalStore(
  withState(initialState),
  withMethods((store) => (
    const httpClient = inject(HttpClient);
    const userStore = inject(UserStore);    

    return loadBooksForLoggedInUser(): void {
      httpClient.get<TalkData>(`/books?userId=${userStore.id()}`)
      // use the result and patch state etc. etc.
    }
  ))

P.s.上面的代码可能并不完美,因为我只是将其写在 stackoverflow 中以表达我的问题。目前我没有任何实际代码可以分享,因为我的问题是假设的。我已经搜索过了,但我找不到任何遇到过这种情况的人,但这感觉很奇怪......因为感觉这应该是相当普遍的。

angular signals ngrx ngrx-signal-store
1个回答
0
投票

我不认为在另一家商店的

withMethods
中使用一个商店是一种代码味道,事实上,我认为这是针对有 2 个具有不同范围的商店的情况的预期架构。 (在您的情况下,很明显用户商店的寿命比书店更长或相同)。

我同意你应该使用一个效果,这样每当用户ID改变时,你就会为当前用户重新加载书籍。我还认为你应该使用 rxMethod 因为 api 是异步的。

withMethods(store => {
     const http = inject(HttpClient);

   return {
     loadBooksForCurrentUser: rxMethod<number>(id$ => id$.pipe(
        tap(/* empty the talk data, set "busy" to true... */),  
        switchMap(id => httpClient.get<TalkData>(/* the url*/)), 
        tap(talkData => // use the result and patch state //)
     ))
   }

}), 
withHooks(store => {
   const userStore = inject(UserStore);
   return {
      onInit() {
          // note - we pass the id signal by reference!!!. 
          // rxMethod subscribes to it so it is called again 
          // whenever it changes
          store.loadBooksForCurrentUser(userStore.id); 
      }
   }
})
  
© www.soinside.com 2019 - 2024. All rights reserved.