Angular:在Facade基类中调用Elf Store的最佳实现方案
在Facade基类中调用Elf Store的最佳实践
问题根源分析
你的代码存在两个核心问题:
SomeRepository中的store是私有属性,外部无法直接访问;SomeFacade错误地注入了Store<SomeRepository>类型,实际上应该注入仓库实例并从中获取Elf store对象。
修正步骤及代码实现
1. 调整仓库类,暴露Elf Store实例
将仓库中的store改为公开属性(或通过getter方法暴露),让Facade能获取到实际的Elf store对象:
export class SomeRepository { // 改为public,让外部能直接访问store实例 public readonly store; constructor() { // 此处可传入初始状态与Elf配置 this.store = createStore({ initialState: { entities: [] } }); } }
2. 优化基类Facade,增加泛型支持
给基类添加泛型以适配不同实体类型,封装通用的Store操作逻辑:
import { Observable } from 'rxjs'; import { select, update } from '@ngneat/elf'; import { setEntities, getEntities } from '@ngneat/elf-entities'; export abstract class BaseFacade<T> { protected store: ReturnType<typeof createStore>; constructor(store: ReturnType<typeof createStore>) { this.store = store; } // 通用的设置实体方法 setEntity(entity: T) { this.store.update(setEntities([entity])); } // 通用的获取实体列表方法 getEntities$(): Observable<T[]> { return this.store.pipe(select(getEntities())); } }
3. 实现子类Facade,正确注入仓库
子类通过依赖注入获取仓库实例,将仓库中的store传给父类构造函数,直接复用基类的通用方法:
import { Injectable } from '@angular/core'; @Injectable({ providedIn: "root" }) export class SomeFacade extends BaseFacade<SomeEntity> { constructor(private someRepo: SomeRepository) { // 将仓库的store实例传给父类 super(someRepo.store); } // 此处可添加子类特有的业务方法 getEntityById$(id: string): Observable<SomeEntity | undefined> { return this.store.pipe(select(getEntityById(id))); } }
4. 组件中正常使用
组件无需修改,直接调用Facade的基类方法即可:
export class SomeComponent implements OnInit { constructor(private readonly facade: SomeFacade) {} ngOnInit() { const entity: SomeEntity = { id: '1', name: 'Jon', age: 30 }; this.facade.setEntity(entity); // 订阅实体列表 this.facade.getEntities$().subscribe(entities => { console.log('当前实体列表:', entities); }); } }
核心优势
- 单一职责:仓库类负责Store的创建与配置,Facade专注于业务逻辑暴露;
- 代码复用:通用的CRUD操作全部封装在基类中,子类无需重复实现;
- 类型安全:泛型支持让基类能适配不同实体类型,避免类型错误。
内容的提问来源于stack exchange,提问作者Ievgen Chernetsov
相关产品推荐
相关产品推荐

