You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

NgRx Signal特性商店能否访问其消费商店的状态?

NgRx Signal特性商店能否访问其消费商店的状态?

当然可以!在NgRx Signal Store的体系里,你完全能让特性商店访问到消费它的主商店状态,我结合你的例子给你讲清楚具体怎么实现。

核心思路

Signal Store的signalStoreFeature本身就支持接收主商店的实例作为依赖,只要我们利用好类型系统和Signal Store暴露的API,就能轻松访问并操作主商店的状态。

修正并实现你的示例代码

首先我们先把主商店withCounters的代码调整得更规范,确保它正确引入特性商店:

import { signalStore, withState } from '@ngrx/signals';
import { withDecrement } from './path-to-with-decrement';

export function withCounters() {
  return signalStore(
    withState({
      counterA: 0
    }),
    withDecrement() // 在这里引入我们的特性商店
  );
}

接下来是关键的withDecrement特性商店实现,我们用泛型来保证类型安全,同时直接访问主商店的状态:

import { signalStoreFeature, withMethods, patchState, type SignalStore } from '@ngrx/signals';

// 用泛型T捕获主商店的状态类型,让特性商店适配任意符合结构的主商店
export function withDecrement<T>() {
  return signalStoreFeature(
    withMethods((store: SignalStore<T>) => ({
      // 打印当前主商店的状态
      logState() {
        console.log(store.state());
      },

      // 根据传入的键名,对对应状态值做减1操作
      decrement(key: keyof T) {
        // 这里做类型断言是因为我们确定操作的是数字类型,你也可以添加类型检查来更严谨
        const currentValue = store.state()[key] as number;
        patchState(store, {
          [key]: currentValue - 1
        });
      }
    }))
  );
}

关键细节说明

  • 类型安全:泛型T会自动推导主商店的状态结构,keyof T能确保你传入的key一定是主商店存在的状态键,避免拼写错误。
  • 直接访问状态store.state()是Signal Store暴露的信号,调用它就能获取当前主商店的最新状态值。
  • 动态更新状态:通过patchState结合计算后的新值,就能完成对主商店状态的修改,这里的动态键语法[key]能适配任意状态键。

在组件中使用

你可以在组件里像这样调用特性商店的方法:

import { Component, inject } from '@angular/core';
import { withCounters } from './path-to-with-counters';

@Component({
  selector: 'app-counter',
  template: `
    <p>Counter A: {{ store.counterA() }}</p>
    <button (click)="store.decrement('counterA')">-1</button>
    <button (click)="store.logState()">Log State</button>
  `
})
export class CounterComponent {
  store = inject(withCounters());
}

额外注意事项

  • 确保你使用的NgRx版本是v16及以上(v17+的Signal Store功能更完善,推荐升级)。
  • 如果你的特性商店只针对特定结构的主商店,可以给泛型添加约束,比如T extends { counterA: number },这样能进一步限制主商店的结构,避免误用。

备注:内容来源于stack exchange,提问作者tobias hassebrock

火山引擎 最新活动