DirectSurface UIDirectSurface UI
开始使用
文档/企业架构

服务与状态

import { createAppContext, createAppContextKey } from 'ds-ui'

DirectSurface UI 不限制业务状态管理方案。它提供的基础能力是上下文、组件状态、命令刷新和生命周期释放。复杂业务可以在这个基础上接入自己的 store、接口服务、缓存服务和审计服务。

状态分层

推荐把状态分成三类:

  • 应用状态:登录用户、租户、主题、全局权限、工作台打开项。
  • 页面状态:查询条件、选中行、编辑草稿、当前文档。
  • 组件内部状态:hover、focus、selected、expanded、scroll offset。

应用状态通常挂在应用上下文。页面状态由页面对象持有或放入页面上下文。组件内部状态由组件自己管理,业务不要绕过组件 API 直接改内部字段。

上下注入示例

const currentRecordKey = createAppContextKey<{ id: string; title: string }>('currentRecord') const pageContext = createAppContext()pageContext.set(currentRecordKey, { id: 'record-001', title: '入院记录' }) const currentRecord = pageContext.require(currentRecordKey)currentRecord.title

这个示例只说明框架如何保存和读取上下文。真实业务对象由业务系统自己定义。

服务注入

服务适合放在应用级上下文或页面级上下文。全局通用服务放应用级,比如通知、权限、字典、API 客户端。跟某个页面强相关的服务放页面级,比如当前病历草稿服务、当前质控任务服务。

如果服务内部持有订阅、缓存或定时器,应通过可释放上下文注册,让页面关闭时自动清理。

状态刷新

业务状态改变后,通常需要做三件事:

  1. 更新页面状态或服务缓存。
  2. 更新组件输入属性。
  3. 触发命令状态重新求值。

组件的布局和绘制会由框架管线处理。业务不要在每个字段变化时强制全局刷新,应尽量只更新相关组件或相关页面。

避免全局单例污染

复杂系统里最常见的隐患是把当前患者、当前文档、当前选中行放成全局单例。这样会导致多 tab、多窗口和弹窗场景互相污染。

推荐规则:

  • 当前登录用户可以是全局。
  • 当前页面参数应该是页面级。
  • 当前编辑对象应该是页面级。
  • 当前选中行应该是组件或页面级。
  • 临时弹窗参数应该是弹窗级。

只有生命周期和可见范围都相同的对象,才应该放到同一个上下文层级。