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

Angular:在Facade基类中调用Elf Store的最佳实现方案

在Facade基类中调用Elf Store的最佳实践

问题根源分析

你的代码存在两个核心问题:

  1. SomeRepository中的store是私有属性,外部无法直接访问;
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:31:00