You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular Signal Store方法内调用另一个方法?含rxMethods适配疑问

问题描述

我有一个包含loadItems()和countItems()方法的Signal Store,希望在loadItems()操作结束时调用countItems()。目前直接在loadItems()内调用countItems()无法实现,请问该如何操作?这种调用是否可行?同时该方式是否适用于rxMethods?

Store代码:

export const sampleStore = signalStore(
  { providedIn: 'root' },

  withState({
    items: [] as string[],
    itemCount: 0,
  }),

  withMethods((store) => ({
    loadItems: () => {
      patchState(store, { items: ['one', 'tow', 'three'] });
      // countItems(); // Not possible
    },
    countItems: () => {
      patchState(store, { itemCount: store.items().length });
    },
  }))
);

组件代码:

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <div>Items: {{sampleStore.items()}}</div>
    <div>ItemCount: {{sampleStore.itemCount()}}</div>
  `,
})
export class App implements OnInit {
  sampleStore = inject(sampleStore);

  ngOnInit(): void {
    this.sampleStore.loadItems();
    // this.sampleStore.countItems();
  }
}

bootstrapApplication(App);

取消注释this.sampleStore.countItems();可得到预期结果,但我希望在loadItems()结束时自动调用countItems()。


解决方案

1. 在loadItems()中通过store实例调用countItems()

你无法直接调用countItems()是因为该函数不在当前作用域内,但当loadItems()执行时,store实例已经完整初始化,所有定义的方法都已挂载到store上,因此可以通过store.countItems()来调用:

withMethods((store) => ({
  loadItems: () => {
    patchState(store, { items: ['one', 'tow', 'three'] });
    store.countItems(); // 直接通过store调用即可
  },
  countItems: () => {
    patchState(store, { itemCount: store.items().length });
  },
}))

这种方式完全可行,因为方法执行时store已经具备所有定义的能力,不会存在引用问题。

2. 复用计数逻辑的优化方案

如果希望进一步复用countItems()的核心逻辑,可以将计数逻辑提取为内部函数,避免重复代码:

withMethods((store) => {
  // 内部复用的计数逻辑
  const updateItemCount = () => {
    patchState(store, { itemCount: store.items().length });
  };

  return {
    loadItems: () => {
      patchState(store, { items: ['one', 'tow', 'three'] });
      updateItemCount(); // 调用内部函数
    },
    countItems: updateItemCount, // 直接复用内部函数
  };
})

这种方式更简洁,也避免了通过store实例调用方法的步骤,同时保证逻辑统一。

3. 针对rxMethods的适配

如果使用withRxMethods(方法返回Observable),可以利用RxJS操作符在异步操作完成后触发计数:

withRxMethods((store) => ({
  loadItems: () => {
    // 模拟异步加载数据
    return of(['one', 'tow', 'three']).pipe(
      tap(items => patchState(store, { items })),
      tap(() => store.countItems()), // 在数据更新后调用计数方法
      catchError(err => {
        // 错误处理逻辑
        return EMPTY;
      })
    );
  },
  countItems: () => {
    patchState(store, { itemCount: store.items().length });
    return of(void 0); // rxMethods要求返回Observable
  },
}))

在组件中调用时,需要订阅Observable:

ngOnInit(): void {
  this.sampleStore.loadItems().subscribe();
}

这种方式同样可行,通过RxJS的tap操作符可以在数据流的任意阶段触发其他方法调用。


内容的提问来源于stack exchange,提问作者Johannes Schacht

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 03:27:25