管理组件类中的 ngrx 信号存储反应性

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

更新到 Angula v17 后,我正在使用“经典”ngrx(基于可观察值)和新的 ngrx/signals 存储重写遗留组件。

我按以下方式定义了一些选择器:

withComputed((state) => ({
    selectOrderId: computed(() => state.orderId()),
    selectAvailableAgents: computed(() => state.availableAgents())
    ... 
})

但是,由于信号的lazy性质,如果我在组件类(而不是模板)中使用这些选择器,那么如果值发生变化,它们将不会动态更新:

const orderId = this.ordersStore.selectOrderId();
// orderId has only the current (at the time of invocation) value from the store

如果

orderId
为空,我需要调用服务来获取它,将值返回给组件并更新存储。最终,为了将这个逻辑保持在一起,我可以在
withMethod
中实现这个逻辑,返回值作为可观察值。
这样我就可以完全跳过选择器调用:

     withMethods((state, ordersService = inject(OrdersService)) => ({

            fetchOrderId$: () => {
                const orderId = state.orderId();

                // If orderId available, do not call the API
                if (orderId) {
                    return of(orderId);
                }

                return ordersService.getOrderId()
                    .pipe(
                        tapResponse({
                            next: (orderId) => {
                                patchState(state, { orderId })
                            },
                            error: (error: HttpErrorResponse) => {
                                console.error("An error occurred: ", error.message);
                            }
                        })
                    )
            }

            //In component class:

            this.orderStore.fetchOrderId$()
                .pipe(
                  takeUntil(this.destroy$)
                )
                .subscribe({
                  next: (orderId) => { 
                       // Here the logic using orderId
                  }
                )}

但是,使用这种方法似乎有点破坏了信号的工作方式。

在这种情况下,我可以将

effect()
视为间接检测信号状态的特定部分何时更改并向组件应用特定操作的唯一方法。但 Angular 文档建议不要使用它们来传播状态,以避免潜在的问题。

因此,最终的方法失去了 ngrx 与可观察量提供的特有的间接性

  • 使用选择器获取值(计算信号)
  • 如果商店中没有可用的值,则调用服务并:
    --> 将其返回给调用者(组件)
    --> 更新商店(patchState)

对于不需要立即获取值的情况,我将使用

rxMethods
来更新状态并在参数发生变化时重新执行。

这是使用 ngrx 信号管理选择器和值的有效方法还是我遗漏了什么?

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

只是为了确保您没有犯我所犯的同样错误: 当您从信号存储中选择信号时,不要调用它(即添加

()
)。如果这样做,信号只会被评估一次,并且您没有信号的句柄,但有该信号中的任何值。 您应该仅在真正需要该值时调用/评估信号。例如在你的html中,如果你想显示当前值

© www.soinside.com 2019 - 2024. All rights reserved.