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

基于@angular-ru/ngxs的一对多关联实体状态管理架构咨询

存储架构设计方案

核心设计思路

摒弃嵌套字典的状态结构,按实体类型拆分独立状态,所有实体统一使用@angular-ru/ngxs/entity提供的标准实体能力,通过applicationId外键做关联映射,既可以直接复用内置的addOne/removeOne/updateOne等操作方法,也能快速适配20+关联API的扩展需求。

各实体状态定义示例

@angular-ru/ngxs的实体模块内置了标准的实体状态结构与操作适配器,无需手动封装字典类型:

import { Injectable } from '@angular/core';
import { State } from '@ngxs/store';
import { EntityState, EntityStateModel } from '@angular-ru/ngxs/entity';

// 1. 主应用实体定义
export interface Application {
  id: string;
  name: string;
  // 其他字段
}
export interface ApplicationStateModel extends EntityStateModel<Application> {}
@State<ApplicationStateModel>({
  name: 'applications',
  defaults: { ids: [], entities: {} }
})
@Injectable()
export class ApplicationState extends EntityState<Application> {}

// 2. 提交记录实体定义,新增applicationId作为关联外键
export interface Commit {
  id: string;
  contributorName: string;
  applicationId: string;
  // 其他字段
}
export interface CommitsStateModel extends EntityStateModel<Commit> {}
@State<CommitsStateModel>({
  name: 'commits',
  defaults: { ids: [], entities: {} }
})
@Injectable()
export class CommitsState extends EntityState<Commit> {}

// 3. 日志实体定义,同理新增关联外键
export interface Log {
  id: string;
  format: string;
  applicationId: string;
  // 其他字段
}
export interface LogsStateModel extends EntityStateModel<Log> {}
@State<LogsStateModel>({
  name: 'logs',
  defaults: { ids: [], entities: {} }
})
@Injectable()
export class LogsState extends EntityState<Log> {}

实体操作示例

所有增删改操作直接调用内置方法,无需手动写展开运算符更新状态:

import { Injectable } from '@angular/core';

@Injectable()
export class AppDataService {
  constructor(
    private commitsState: CommitsState,
    private logsState: LogsState
  ) {}

  // 批量新增某应用的提交记录
  saveAppCommits(appId: string, commits: Commit[]) {
    // 内置方法自动处理ids、entities的更新
    this.commitsState.addAll(commits);
  }

  // 新增单条日志
  addSingleLog(log: Log) {
    this.logsState.addOne(log);
  }

  // 删除单条提交记录
  deleteCommit(commitId: string) {
    this.commitsState.removeOne(commitId);
  }
}

按应用ID查询数据的选择器实现

通过外键过滤即可快速获取指定应用的关联数据:

import { createSelector } from '@ngxs/store';

// 提交记录选择器
export class CommitsSelectors {
  static getByAppId(appId: string) {
    return createSelector([CommitsState], (state: CommitsStateModel) => {
      return state.ids
        .map(id => state.entities[id])
        .filter(commit => commit.applicationId === appId);
    });
  }
}

// 组件中使用
@Component({ /* 组件配置 */ })
export class AppDetailComponent {
  // 直接订阅指定应用的提交记录
  @Select(CommitsSelectors.getByAppId('当前应用ID'))
  appCommits$: Observable<Commit[]>;
}

20+关联API的扩展方案

  • 每个新的关联API对应的数据实体单独定义一个实体状态,统一继承EntityState基类,所有增删改逻辑直接复用内置方法,无需重复编写状态更新代码
  • 所有关联实体统一添加applicationId外键,通用选择器逻辑可以封装为公共方法,无需为每个实体单独写过滤逻辑
  • 状态全量扁平化,无嵌套结构,后续排查问题、做数据持久化都更易处理

内容的提问来源于stack exchange,提问作者Gaultier Romon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:24:02