如何在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
相关产品推荐
相关产品推荐

