mcpField
C
custom-angular-component-creator

custom-angular-component-creator

github.com/datex设计与 UI55 次安装
代码仓库

关于 custom-angular-component-creator

custom-angular-component-creator 是用于在 Datex Studio 中编写或编辑自定义 Angular 组件的技能,面向需要定制界面的开发者。它通过 dxs ng 创建本地轻量 harness、预览截图,并在 push 后写入 Studio;数据采用真实类型化数据源,预览使用模拟数据。

主要功能

  1. 01编写独立 Angular 组件
  2. 02通过 dxs ng 创建和拉取组件
  3. 03本地 harness 预览并生成截图
  4. 04嵌入现有应用配置组件
  5. 05使用类型化数据源及模拟预览数据
  6. 06推送组件至 Datex Studio

适用场景

  1. 01构建定制图表、仪表板或可视化
  2. 02在自定义界面中嵌入生成控件
  3. 03将自定义组件用作容器标签页内容

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/datex/skills --skill custom-angular-component-creator

安装后在 Claude Code 中输入/custom-angular-component-creator确认已加载。

附带文件references/custom-angular-components.md

详细介绍

自定义 Angular 组件创建器

在分支上创作或编辑 Datex Studio 自定义 Angular 组件(CAC,configurationTypeId: 36)。CAC 是由作者编写的独立 Angular 组件——你需要编写实际的 component.ts / .html / .scss,而不是声明式 JSON 配置。它在生成的应用中运行,并注入真实的平台上下文($datasources、$flows、$shell 等),因此可用于实现声明式组件(grid / form / hub / selector / editor)无法表达的 UI:定制图表、仪表板、可视化和自定义布局。

CAC 也可以在模板中嵌入现有应用配置——将其声明为组件引用(先从 selectors 开始;此契约适用于各种组件类型),代码生成器便会将生成的组件导入 CAC 的作用域,让真正生成的控件(例如 selector 下拉菜单)在自定义 UI 中渲染。

嵌入提示:selector 会生成两个变体——_single 和 _multi——因此引用一个 selector,就能获得单选和多选控件供你选择。嵌入的控件会将配置本身的属性作为组件输入/输出公开(例如,selector 会将其每个 datasource 参数作为输入公开,输入名称由参数 ID 决定,并公开其选中值和显示文本输出)。要查找被引用配置公开的确切标签和输入/输出,请读取物化 harness 中生成的组件——@Component 的 selector 就是要使用的标签,@Input / @Output 成员就是要绑定的内容——不要靠猜。

此技能使用的 CLI 接口与其他所有创建器都不同。 这里没有 dxs configuration upsert customangularcomponent 这种手动创作路径——CAC 创作通过 dxs ng 命令系列完成。该命令会物化一个轻量 harness(由服务器为该分支生成,包含单个组件、真实的类型化上下文和存根服务),让你在本地编辑两个作者区域,并在每次迭代时渲染一张截图。只有执行 dxs ng push 后,内容才会在 Studio 中创建。

数据模式(固定默认值——绝不询问)

无论 CAC 何时显示数据,这些数据都来自真实的类型化 datasource——而且如何接入数据不是要询问用户的问题。不要询问是否使用真实数据、示例数据、@Input 或其他数据来源:所有组件都使用固定模式。

  • 创作循环(CLI / dxs ng preview): 组件通过类型化的 this.$datasources.<ref> 存根读取数据,但预览使用的是模拟数据——dxs ng data generate 会生成 mocks/harness-mocks.json,你再用有代表性的值填充它(这些值来自真实的 dxs 查询)。创作预览绝不会访问真实数据。
  • push 之后(生成的 Studio 应用): 相同的类型化 $datasources.<ref> 调用会在运行中的应用里访问真实 datasource / 真实数据。组件在运行时始终依赖 datasource。
  • 分支上缺少 datasource? 先用 schema-explorer 探查,再用 datasource-creator 创建一个与真实 schema 匹配的 datasource,并在物化 harness 之前执行 upsert,以便 harness 为存根生成类型。绝不要在组件主体中回退到内嵌示例行,也不要使用类型转换($datasources as any)。

一句话概括:真实的类型化 datasource + 创作时使用模拟数据,push 后使用真实数据——每个 CAC 都遵循此模式,无需询问。示例数据只存放在 mocks/harness-mocks.json 中(临时使用,绝不 push);组件主体应保持简洁,并提供真实的空数据、加载和错误状态。具体操作请参见第 3 阶段。

CLI 优先——禁止变通(硬性规则)

dxs CLI 是此技能唯一获准使用的操作界面——所有 Studio 状态的读取和写入,以及创作循环的每个步骤(create/pull、data generate、preview、push),都必须通过 dxs 完成。如果 CLI 功能不足,应将这一缺口报告为待修复的 CLI 问题,不要绕过 CLI——能够“完成任务”的变通做法会掩盖缺陷,而之后的每次会话都会再次遇到这个缺陷。

  • 从 dxs 获取事实,不要依赖其他渠道。 字段形状、配置内容、架构、分支状态都有对应的 dxs 命令。对命令输出使用普通的 head/grep 没问题;但不允许通过脚本解析配置 JSON(jq/python),也不允许读取原始平台构件。
  • 根据 CLI 可观察到的证据推断服务端约定。 validate/upsert 的拒绝信息会指出预期的服务类型,而分支上现有的有效配置(dxs configuration get)会展示被接受的形状——这两者已足够。不要打开平台源代码仓库来逆向分析约定。
  • 需要变通时,应提交 Bug 报告,而不是把变通当作技巧。 如果任务看似需要终止残留进程、编写脚本绕过 CLI 输出格式、驱动 CLI 已封装的工具(例如,在 dxs ng preview 之外截取屏幕截图),或手动编辑生成的 JSON——请停下来,告知用户 CLI 存在的缺口或 Bug,并协商后续步骤。
  • 挂起和孤儿进程属于应报告的缺陷。 如果 dxs 命令阻塞终端、遗留持有文件锁的子进程,或泄漏临时状态,这就是 CLI 生命周期 Bug。记录完整的症状链(命令、错误代码、遗留进程/文件),以便修复;解除阻塞的终止操作必须在报告之后进行,不能当作未加说明的常规操作。

每个屏幕仅使用一个 CAC(硬性规则)

一个设计/屏幕应作为一个 CAC 来编写——绝不能拆分成多个 CAC 再组合。组合应通过嵌入式平台组件(组件引用:优先使用选择器)和 $shell 对话框打开器实现,而不是将 CAC 嵌套在 CAC 中。如果设计对单个组件来说过于庞大,应精简设计,而不是增加组件数量。

将 CAC 用作标签页内容

CAC 可以作为中心页、编辑器、卡片或仪表板中标签页的内容——与承载网格和表单的插槽相同。在容器的标签页设计器中,选择 Custom Angular Component 作为标签页内容类型,引用已推送的 CAC,并通过标签页的参数绑定其 @Inputs(标签页连接的是 CAC 的 inParams/outParams)。平台会为每个 CAC 生成标签页内容约定,预留三个成员名称——refresh、$refreshEvent 和 outParamsChange。切勿将这些名称声明为 outParam 或 @Output,也不要在主体中重新声明两个生成的 @Output($refreshEvent、outParamsChange)——名称冲突会导致重复成员编译错误。唯一的例外是主体中的 refresh() 方法,它是获准的重写方式:若要在容器刷新时重新加载 CAC,请在主体区域实现 refresh(),它会替换生成的默认实现(默认实现会重新运行 ngOnInit())。

参考资料

依赖项

  • requirements-gathering 技能 — 如果对话上下文中尚无简报(或目标截图),则调用该技能来生成简报(或收集目标截图)。CAC 的核心价值就是定制 UI,因此具体的视觉目标对 CAC 的价值高于对任何其他组件的价值。
  • schema-explorer 技能 — 当组件通过 $datasources 读取 Footprint 数据时调用,以确认实体/字段存在,再进行连接。
  • datasource-creator 技能 — 当组件需要的某个数据源/工作流在分支上尚不存在时调用(先创建,再从组件中引用,并为预览添加模拟数据)。

先决条件(一次性,由宿主提供)

dxs ng 循环需要可访问的 Datex API——开始前请确认以下事项(参见 references/custom-angular-components.md → Prerequisites):

  1. 目标分支对应的 Datex API 可访问。 测试框架端点会在服务端运行代码生成,且不受环境限制——部署的映像会在其运行时阶段安装 Node 和 codegen/node_modules,正是为了让 API 能够按需运行代码生成。因此,create/pull 会针对 CLI 配置的任何 Datex Application API 工作,无论是 dev、qa 还是 prod。 (请勿与应用发布混淆,发布确实受 dev 环境限制——在 Development 之外,发布会交由 Azure DevOps 管道处理。此限制不适用于测试框架端点。)
  2. 已通过身份验证——dxs auth status 会显示已登录的身份。
  3. agent-browser(无头截图)——通过非作用域 npm 包安装:npm install -g agent-browser,然后运行 agent-browser install。(包名不是 @anthropic-ai/agent-browser——该名称会返回 404。)

CLI 生命周期 — dxs ng 系列

命令是否联网?是否操作 Studio?功能
dxs ng create <Name> -b <branch> [-d <dir>]是否构建起始配置 → 服务端为分支生成轻量测试架构 → 在本地生成 <name>/angularapp/… + manifest.json + mocks/。不会在 Studio 中创建任何内容。
dxs ng pull <name> -b <branch> [-d <dir>] [--force]是否为现有 CAC 执行相同的生成操作(用于编辑现有内容的入口)。如果文件夹已存在,会报出结构化的 DXS-NG-048 错误;--force 会删除整个文件夹(先停止正在运行的预览服务本身),然后根据服务端的实际状态重新生成。
dxs ng data generate <folder> -b <branch>是否使用组件所用 $datasources/$flows 的类型化占位符填充 <folder>/mocks/harness-mocks.json。
dxs ng preview <folder> [-o out.png] [--refresh] [--clean]否(本地)否在本地运行测试架构,并为组件截图 → <folder>/render.png。--refresh -b <branch> 会在 manifest/IO 变更后重新获取测试架构;--clean 会重置卡住的服务,并拆除 agent-browser 会话(守护进程、Chrome 进程树、过期状态文件)。
dxs ng push <folder> -b <branch>是是提取两个区域 + manifest.json → 执行 type-36 的 upsert。首次 push 会在 Studio 中创建组件;服务端会在 upsert 时进行验证(强制门禁)。
dxs ng stop <folder>否(本地)否停止文件夹的常驻预览开发服务及其 agent-browser 会话(通过身份校验的锁终止操作,并移除锁)。此操作幂等(没有正在运行的进程时,stopped: false)——完成后用于清理;切勿手动读取锁或运行 taskkill。
dxs ng list -b <branch>是否列出分支的 type-36 组件。

传给 create 的 <Name> 必须使用帕斯卡命名法(OutboundCommandCenter);引用名称会转换为驼峰命名法(outboundCommandCenter),选择器使用 kebab-case app-outbound-command-center(自动生成——即 create 输出并存储在 manifest.json 中的值),文件名为 app.outboundCommandCenter.component.{ts,html,scss}。

工作流

[Phase 1: Setup + Requirements]
Follow branch-setup.md for branch selection (NEVER assume a branch ID)
Confirm prerequisites (API reachable, auth, agent-browser)
        |
[requirements brief / TARGET SCREENSHOT in context?]
  +-----+-----+
  |            |
 YES          NO -> invoke `requirements-gathering` (capture the visual target)
  +-----+------+
        |
[Phase 2: Materialize the harness]
dxs ng create <Name> -b <branch>        (new component)
   -- or --
dxs ng pull <name> -b <branch>          (edit an existing one)
        |
[Phase 3: Author the two regions]
Edit <name>/angularapp/src/app/app.<ref>.component.ts:
   __COMPONENT_TYPES__  region -> imports / interfaces / types
   __COMPONENT_BODY__   region -> fields / methods / getters / lifecycle
Edit app.<ref>.component.html and .scss.
NEVER touch the wrapper class line, the @Component decorator, the
constructor, or the //#region ... //#endregion sentinels.
        |
[real data?] -> dxs ng data generate <folder> -b <branch>   (seed mocks)
        |
[Phase 4: Preview loop (screenshot-driven)]
dxs ng preview <folder>        -> writes <folder>/render.png
Read render.png. Compare to the target. Edit regions. Re-preview.
Repeat until it matches. (First preview ~15-46s cold; each later ~10s.)
        |
[Phase 5: Push + verify]
dxs ng push <folder> -b <branch>     (creates in Studio; server validates)
dxs ng list -b <branch>              (confirm it landed)
dxs ng pull <name> -b <branch> -d ./roundtrip   (optional round-trip check)

阶段详情

阶段 1:设置 + 需求
  1. 按照 ../datex-studio-shared/branch-setup.md 选择分支。切勿假定或重复使用分支 ID——即使本次会话中较早时出现过,也要让用户确认。确认上述前置条件。
  2. 检查上下文中是否有需求说明。对于 CAC,价值最高的输入是具体的视觉目标——目标截图,或对布局、数据和交互的精确描述。如果没有,请调用 requirements-gathering。目标截图能让阶段 4 成为以目标为基准、逐步收敛的过程。
阶段 2:生成轻量框架

运行 dxs ng create <Name> -b <branch>(新建)或 dxs ng pull <name> -b <branch>(已有)。传入 -d components,让工作副本位于共享的 components/<Name>/ 目录下(这是 CAC 工作目录的约定),而不是当前目录。此命令会让服务为分支生成轻量框架,并在本地生成文件:

<name>/
  angularapp/…       # the runnable light harness (one component + real typed context + stub services)
  manifest.json      # identity + IO (inputs/outputs) + datasource/flow refs + displayModes
  mocks/             # fixtures the harness $datasources/$flows read during preview

此步骤不会在 Studio 中创建任何内容。请参阅 references/custom-angular-components.md → The light harness。

编辑已有组件(pull)。 pull 是编辑已有组件的入口,它会忠实地往返同步 Studio 中的两个作者区域以及 .html/.scss。如果目标文件夹已存在,则会报出结构化的 DXS-NG-048 错误,并列出两种获准的处理方式——明确选择同步方向:

  • 保留我的本地工作,刷新轻量框架 → dxs ng preview <folder> --refresh -b <branch> — 唯一保留区域内容的同步方式(保留作者编写的区域、模板、样式、manifest.json、mocks/、node_modules)。
  • 丢弃本地内容,采用服务端版本 → dxs ng pull <name> -b <branch> -d <dir> --force — 删除整个文件夹(与 dxs report download --force 的行为一致),然后重新生成文件。CLI 会通过经过身份校验的 serve 锁自行停止仍在运行的预览开发服务器——切勿手动终止进程——如果目标看起来不像 CAC 工作副本,则会拒绝操作(DXS-NG-049)。

有三项内容永远不会通过服务端往返同步,因此使用 --force 拉取后,请恢复它们:(1) manifest.datasources 会变为空(持久化配置只存储标识以及 inParams/outParams)——请将条目重新添加为对象 { "name": "<ref>", "ref": "<ref>" },切勿使用裸字符串(字符串会导致下一条 dxs ng 命令中的 manifest 验证失败);(2) mocks/ 会变为空——请使用 dxs ng data generate 重新生成数据并填充,或还原之前的文件;(3) node_modules 会被删除——下次运行 preview 时会重新执行 npm install(耗时数分钟)。重新添加 manifest 条目后的首次 preview 会报告 refetched: true(manifest 编辑改变了 IO 签名,从而触发自动重新生成)——这是预期行为,并非错误。

阶段 3:编写两个区域

你只能编辑 <name>/angularapp/src/app/app.<ref>.component.ts 中的两个作者区域,以及同级的 .html 和 .scss:

//#region __COMPONENT_TYPES__
//   imports, interfaces, type declarations  (spliced verbatim on push)
//#endregion __COMPONENT_TYPES__

// ...generated @Component + class wrapper + constructor (DO NOT EDIT)...

  //#region __COMPONENT_BODY__
  //   fields, methods, getters, lifecycle body  (spliced verbatim on push)
  //#endregion __COMPONENT_BODY__

切勿更改包装器的 class 行、@Component 装饰器、构造函数或 //#region … //#endregion 标记行——push 会从标记之间提取你的工作,因此损坏这些内容会导致提取失败。构造函数已注入真实上下文($datasources、$flows、$shell、$utils、$settings、$reports、$localization、$operations、$userSettings、$frontendFlows),并使用真实分支类型,因此代码体中应使用 this.$datasources.… 等写法——切勿直接使用 HttpClient。已导入 SharedModule,因此模板中可使用 Angular 指令(*ngFor、*ngIf、[ngClass]、[style.*])以及 Material/AG-Grid/ApexCharts。

遵循 Datex 设计系统进行样式设计——CAC 不会自动获得任何样式,因此必须应用设计系统,否则外观会显得格格不入。不可妥协的原则:参考现有设计,不要自行发明(复制最相近的现有组件的标记结构和类);使用 var(--…) 主题令牌,绝不硬编码十六进制值(硬编码的十六进制值会破坏深色模式,也会破坏填充式控件系统所依赖的令牌);组合使用真实的 datex-* 类名(datex-button primary、field-container、grid-table-*、card datex-card、widget-container 等),而不是编写专用 CSS;Fluent 图标只能放在 <i> 上;使用句首字母大写的大小写格式,每个屏幕只放一个主按钮。有关令牌变量、完整的组件类名列表以及编译后 CSS 的陷阱,请阅读 ../datex-studio-shared/design-system/(从 02-tokens、03-components、06-traps 开始)。 如果组件会读取真实数据,请运行 dxs ng data generate <folder> -b <branch>,为 mocks/harness-mocks.json 填充初始数据,然后填入逼真的值,让预览呈现有代表性的数据。如果不确定数据源或实体是否存在,请先调用 schema-explorer;如果需要创建数据源或实体,请调用 datasource-creator。

对清单进行 IO 更改(新增 @Input/@Output)需要配置代码生成:编辑 manifest.json,然后使用 --refresh -b <branch> 重新预览;重新生成的 harness 会为 this.inParams.<name> 指定类型,并通过 this.<output> 发出事件。区域、模板和样式的编辑完全在本地进行(无需 --refresh)。

生命周期钩子要写在主体中。 直接在 __COMPONENT_BODY__ 中实现 ngOnInit / ngOnChanges / ngOnDestroy(例如,使用 async ngOnInit() 加载数据)。代码生成只会为你未实现的钩子生成存根,因此,重新获取会使二者保持一致;但如果 IO 未发生变化,直接运行 preview 不会重新获取,导致你的钩子与仍存在的生成存根重复(产生编译错误)。因此,请在触发重新获取的 IO 更改中一并添加钩子,或者添加钩子后运行一次 preview --refresh -b <branch>。对于非 @Input 的组件内交互状态(例如模式切换),请保留一个普通字段,并在 ngOnInit 中用输入值初始化它——无需更改清单,因此预览会保持就绪。

数据源——先创建,再通过带类型的访问方式引用,不使用固定样例数据。 数据源是真实的分支配置:在物化 harness 之前,使用 datasource-creator 创建数据源(dxs datasource generate → validate → dxs configuration upsert datasource),这样生成的 harness 才会为 this.$datasources.<ref> 存根指定类型。manifest.datasources 只会声明依赖项,不会创建数据源。请使用带类型的访问方式读取它(await this.$datasources.<ref>.getList({…})),不要进行类型转换。如果缺少数据源,该带类型的引用会导致编译错误——这正是你想要的快速失败行为:修复配置(创建并 upsert,然后重新物化),不要通过类型转换绕过错误($datasources as any),也不要回退到内嵌样例数据。如果在物化后才添加了数据源,而存根尚未出现,请重新物化(dxs ng pull / preview --refresh -b <branch>),并在依赖它之前确认它已列在 angularapp/src/app/app.datasource.index.ts 中。样例/预览数据只能放在 mocks/harness-mocks.json 中(临时数据,绝不推送)——不要放在组件主体中,因为组件主体会原样插入 Studio 配置。**如需了解数据源的字段结构,以便映射行数据,请使用 CLI——切勿手动解析配置 JSON:**既然你无论如何都会在物化之前执行 upsert,就可以使用 dxs report datasource-fields <ref> -b <branch> 读取权威字段结构(结果类型 + 参数 + 扁平字段路径 + 集合),并使用 dxs datasource validate <file> -b <branch> 验证本地文件(发现错误时会以 1 退出——这表示验证报告发现了问题,并非 CLI 出故障:读取 validation_errors、修复后重新运行);不要用 jq/python 从 outParams/queryOptionsObjectTypeDef 中提取字段,并记住,执行 dxs ng create 后,this.$datasources.<ref> 已带类型。参见 references/custom-angular-components.md → 读取真实数据。

阶段 4:预览循环(基于截图)
dxs ng preview <folder>          # -> <folder>/render.png

读取 render.png,将其与目标进行比较,编辑区域、模板或样式,然后重新运行 preview。这是核心循环,也是 Agent 发挥价值的地方:读取 PNG,与目标截图进行比较,进行调整,然后重复,直到匹配为止。类型/模板错误也会在此处显现(测试工具会编译真实组件)。耗时(本地):create 后首次运行 preview 时,需要一次性执行 npm install(几分钟),然后编译约需 15–46 秒;此后每次运行 preview 约需 10 秒,编辑后热重载约需 4 秒。冷编译等待由内部处理(没有超时参数);如果服务或浏览器会话卡住,请使用 --clean——它会重置二者,包括崩溃运行遗留的过期 agent-browser 会话状态。

preview 会捕获组件的默认渲染状态,不会点击。如果某个模式/变体是通过组件内 UI(而非 @Input)切换的,请临时设置该默认状态(或通过 @Input/模拟数据驱动),以便对每个变体截图。对于真正的交互状态(点击选择、切换开关、面板),请改为使用 agent-browser 操作已提供的测试工具:从 <folder>/.dxs-serve.lock 读取端口,然后执行 agent-browser open http://127.0.0.1:<port> → wait '<css>' → click '<css>' → screenshot out.png——这样验证的是真实处理程序的接线,而非模拟的默认状态。

阶段 5:推送并验证
dxs ng push <folder> -b <branch>     # first push CREATES it in Studio; server validates on upsert
dxs ng list -b <branch>              # confirm it appears
dxs ng pull <name> -b <branch> -d ./roundtrip   # optional: confirm the regions round-trip
dxs ng stop <folder>                 # done for now? dispose of the warm dev server + browser session

push 是唯一会写入 Studio 的命令。服务器会在创建或更新时运行配置验证器(这是硬性门槛——它能识别 CAC 配置);如果组件引用了分支上不存在的数据源,或以其他方式未通过验证,就会被拒绝。请修复报告的问题,然后再次推送。如果区域哨兵标记受损,push 也会在本地失败(发起任何网络调用之前)——这就是“不要触碰哨兵标记”规则生效的情形。

数据源连接预检(DXS-NG-047)。 在创建或更新之前,push 会验证 CAC 使用的每个本分支数据源——包括 manifest.datasources 和组件正文中未限定名称的 $datasources.<ref> 调用的并集(因此过期的清单无法绕过检查)——是否存在于该分支上,并且是否指定了该分支实际定义的 API 连接设置。这一点很重要,因为测试工具中的模拟不会触及连接:即使 Studio 会在数据源上标记 “Missing API Connection setting <name>”,预览仍会显示为绿色;而推送成功也绝不应让人误以为真实的代码生成构建可行。遇到 DXS-NG-047 时:检查 dxs source branch settings <branch>;使用 dxs datasource generate 针对此分支重新生成数据源(它会自动解析设置);如果应用完全没有 API 连接,请先在 Studio 中接入一个(CLI 不会创建连接)。在尚无任何连接的应用上进行有意的纯模拟开发时,可用 --skip-connection-check 跳过此门槛。包数据源(Module/ref、$datasources.<Module>.<ref>)不受此检查限制——其设置会通过引用重映射进行解析。

预检清单

  1. 已与用户确认分支(绝不自行假定);前置条件已就绪(API 可访问、身份验证正常、agent-browser 可用)。
  2. 仅编辑了两个区域、.html 和 .scss——包装类所在行、@Component、构造函数和 //#region 标记均未改动。
  3. 没有使用原始 HttpClient / 直接调用后端——数据通过 this.$datasources / this.$flows 获取;UI 操作通过 $shell / $flows 执行(参见 calling-conventions)。
  4. 已填充 Mock 数据(dxs ng data generate);如果组件会读取 $datasources/$flows,还需填入有代表性的数据,让预览渲染出贴近真实的数据。
  5. 修改 manifest.json 的 IO 后,运行 preview --refresh -b <branch>(新增 @Input/@Output 需要重新连线代码生成)。引用的数据源必须已存在于分支上(最好在物化前先用 datasource-creator 创建),并通过 $datasources 的类型化访问读取——缺少数据源会导致编译错误,必须修复,绝不能通过强制类型转换绕过;示例数据保留在 mocks/ 中。参见 Phase 3 中的数据源说明。
  6. 预览 PNG 与目标一致——循环迭代已收敛,渲染中不再有编译/模板错误。
  7. displayName 不超过 100 个字符——它会成为配置的 title/description(没有单独的 manifest description 字段)。
  8. 推送后已验证——dxs ng list -b <branch> 会显示该项;也可选择运行 dxs ng pull … -d ./roundtrip,往返验证这些区域。

清理——工作副本占用空间较大

物化后的工作文件夹约占 700 MB,其中约 85% 是 angularapp/node_modules。文件夹不是交付物——push 后,Studio 中的配置才是。

成功 push 后(通过 dxs ng list -b <branch> 验证),询问用户是否清理——绝不默默清理。首先使用 dxs ng stop <folder> 停止常驻开发服务器及其 agent-browser 会话——该命令会进行身份校验后再停止(验证 PID + 映像,绝不盲目终止),并清理浏览器会话/守护进程和锁文件;该操作可重复执行,因此无论如何都应调用。绝不要手动读取 .dxs-serve.lock 或运行 taskkill——对于早于 stop 命令的 CLI,手动操作只是权宜之计,并非推荐方法。(dxs ng preview <folder> --clean 是另一个生命周期命令:它执行的是重置,而不是停止——采用相同的清理流程,然后启动新服务器;预览卡住时使用它,释放资源时使用 stop。)然后提供以下两种清理级别。分两级释放磁盘空间:

  • **精简(会话之间的默认操作):**删除 <folder>/angularapp/node_modules(约 600 MB)、<folder>/angularapp/.angular(构建缓存,约 100 MB)和 <folder>/.dxs-install-ok 标记文件(它与 node_modules 配套——只有两者都存在时,preview 才不会重新安装)。所有编写的内容都会保留,可恢复,约占 16 MB;下次运行 preview 时会重新执行 npm install(需要几分钟),并进行冷编译。数据丢失风险为零。
  • 完全删除(组件已完成时):仅在确认配置已存在于 Studio 中(dxs ng list -b <branch>)后执行。如果目标是获取全新的工作副本,完全不要手动删除——dxs ng pull <name> -b <branch> -d <dir> --force 会完成整个操作(自行停止运行中的开发服务器、删除并重新物化);若残留锁定文件导致失败,会显示结构化错误 DXS-NG-049。若删除后不再重新拉取(最终清理):先运行 dxs ng stop <folder>,再删除文件夹。少见的残留情况:之前崩溃的服务器可能遗留锁文件已不再跟踪的孤立子进程(node.exe、esbuild.exe),因此,如果删除仍因文件被锁定而失败,请清理命令行中引用该文件夹的进程,并将此问题报告为 CLI 生命周期错误。dxs ng pull 会忠实地重新物化两个区域、.html 和 .scss,但 mocks/harness-mocks.json、捕获的目标/备注文件以及 manifest.datasources/componentRefs 不会往返保留——重新拉取后需重新填充/添加它们。

绝不要完全删除尚未推送的工作副本——编写的区域不会在其他地方留存。

常见错误

错误做法修正方法
询问用户组件应如何获取数据(真实数据还是示例数据、使用 @Input 还是 datasource)不要询问——数据模式是固定的。使用真实的类型化 datasource + mocks/ 数据用于创作预览;push 后使用真实数据。请参阅数据模式(固定默认值——切勿询问)。
手动编写 JSON 请求体并运行 dxs configuration upsert customangularcomponentCAC 通过 dxs ng(regions + harness + preview)创作,而非通过 JSON 往返。请使用 dxs ng create / preview / push。
编辑两个 regions 以外的内容(触碰 wrapper class、@Component、constructor 或 //#region 哨兵标记)push 会提取哨兵标记之间的代码。其他位置的编辑会在 push 时丢失,或导致提取失败。请只修改 __COMPONENT_TYPES__、__COMPONENT_BODY__、.html、.scss。
安装 @anthropic-ai/agent-browser(404)该软件包的名称不带作用域,即 agent-browser:npm i -g agent-browser && agent-browser install。
preview 报告 ng serve did not become ready(DXS-NG-042)通常是首次冷编译耗时较长——可通过 DXS_NG_SERVE_TIMEOUT(秒)延长超时时间,然后重新运行;使用 --clean 重置卡住的服务。在 CLI ≤0.4.13 中,相对文件夹参数也会导致此问题(开发服务器因脚本路径解析错误而立即退出;此问题已修复——在该版本中可传入绝对路径作为变通方法)。如果在当前 CLI 中仍然出现此问题,那就确实是编译问题——检查 ng build。
preview 因 DXS-NG-053 失败(agent-browser 'wait' timed out)——并由此认定组件已损坏截图超时 ≠ 渲染失败:组件通常已成功编译并提供服务(与 DXS-NG-042 ng serve did not become ready 不同,后者才是编译失败)。预热的服务也可能已过期。使用 --clean 重新运行,然后用 agent-browser 打开 .dxs-serve.lock 中的端口,并检查 app-<ref> 是否有内容,以验证实际渲染——不要追查不存在的代码错误。
期望预览/打开其他组件(或通过 $shell 打开它们的对话框)harness 只会将你的候选组件设为真实组件;对其他组件调用 $shell.open<X>Dialog(...) 时,会生成可编译但无法在预览中打开的 stub。$datasources/$flows(真实分支)和你自己的 UI 均可正常使用。
期望组件在 create / preview 后出现在 Studio 中create/pull/data generate/preview 都只是临时操作。只有 push 会写入 Studio(首次 push 时会创建组件)。
在 body 中使用 HttpClient 或 fetch请使用注入的 $datasources / $flows;它们是真实、类型化的,并且可在预览中使用 mock。原始 HTTP 请求无法获得分支的 auth/context。
组件使用了 datasource,但预览渲染为空运行 dxs ng data generate 并填充 mocks/harness-mocks.json——预览时 harness 的 $datasources/$flows 会读取这些 fixture(无需后端)。
添加了 @Input/@Output,但 preview 没有体现IO 更改需要重新执行 codegen 连接:更新 manifest.json,然后运行 dxs ng preview <folder> --refresh -b <branch>。
期望 manifest.datasources 创建或连接 datasource它两者都不会做。请先使用 datasource-creator 创建 datasource(运行 dxs datasource generate/validate/configuration upsert datasource),最好在实例化之前完成,这样 harness 才能为 $datasources.<ref> stub 生成类型;manifest.datasources 只声明依赖项。
通过类型转换绕过缺失的 datasource($datasources as any)或使用 fixture 备用数据这是反模式:它会将假数据发布到 Studio,并掩盖连接问题。缺失的 datasource 应当导致编译错误——请创建/更新 datasource 并重新实例化(pull/--refresh)来修复,然后使用类型化的 this.$datasources.<ref>。
在 body 中嵌入示例/fixture 行(或添加“之后会被真实 datasource 替换”的注释)body 会原样拼接到推送的 type-36 配置中,因此 fixture 和 WIP 注释都会进入生产环境。请保持 body 简洁——使用类型化 datasource 读取,并提供真实的空数据/加载中/错误状态;示例数据只放在 mocks/harness-mocks.json 中。
手动解析 datasource 配置 JSON(使用 jq/python,或查看 outParams/queryOptionsObjectTypeDef 来了解字段结构)请使用 CLI。先执行 upsert(这本来就是实例化前的必要步骤),然后运行 dxs report datasource-fields <ref> -b <branch> 获取字段列表;对于本地文件,使用 dxs datasource validate/context <file> -b <branch>。运行 dxs ng create 后,this.$datasources.<ref> 已有类型——你很少需要手写行类型。切勿编写脚本解析 JSON。
--refresh 渲染正常,但之后的 preview 显示编译错误--refresh 重启时可能会在重新编译错误提示层显示之前就截图。请再次运行普通 preview 确认,并 grep harness 的 app.datasource.index.ts,查看实际连接了哪些 datasources。
服务器拒绝 push该操作运行了 validator(硬性门槛)。请修复它报告的问题(通常是分支中缺少 datasource ref——调用 schema-explorer/datasource-creator),然后再次 push。
push 因 DXS-NG-047 失败(datasource connection 预检)CAC 使用的 datasource 在分支中缺失,或者其 apiSettingName 指向了分支中未定义的 API connection setting——即使预览渲染正常,Studio 仍会报告此问题(mock 不会访问 connections)。请针对此分支重新生成 datasource(dxs datasource generate 会自动解析该 setting),或先在 Studio 中连接对应的 connection;只有在有意仅使用 mock 开发时,才使用 --skip-connection-check。请参阅 Phase 5。
将 preview 成功显示为绿色视为 datasource 连接在 Studio 中正常工作的证明预览数据来自 mocks/——harness 不会访问 API connection,因此损坏的 apiSettingName 连接在 Studio(或 push 预检)报告之前不会显现。push 上的 DXS-NG-047 门槛才是可靠的检查;不要轻易绕过。
push 在任何网络请求发出前就在本地失败某个 region 哨兵标记已损坏。请准确恢复 //#region __COMPONENT_TYPES__/__COMPONENT_BODY__ 标记,或重新 pull 并重新应用编辑。
pull 返回的 mocks/ 为空且没有 manifest.datasources(正在编辑现有 CAC)这是预期行为——有三项内容不会往返:manifest.datasources、mocks/、node_modules。请重新添加 datasources(使用对象而非字符串),重新填充 mocks/(运行 data generate 并填写),让 preview 重新安装。两个 regions 和 .html/.scss 均可正常往返。请参阅 Phase 2。
手动删除工作文件夹(或终止开发服务器进程)以绕过 pull 的文件夹已存在错误使用 flags,而非手动清理:preview --refresh 会保留本地工作;pull --force 会丢弃本地工作,并自行停止正在运行的开发服务器(通过身份检查的 lock kill)。残留的锁定文件错误会以结构化的 DXS-NG-049 报告,而非原始 WinError。
预览结束后手动读取 .dxs-serve.lock 并用 taskkill 终止开发服务器这是 stop 命令出现之前的变通方法。dxs ng stop <folder> 是用于清理的命令:通过身份检查终止进程树 + teardown agent-browser session + 移除 lock,可重复执行(没有正在运行的服务时返回 stopped: false)。完整生命周期由 CLI 管理:替换时 pull --force 会清理,preview --clean 会重置,stop 会清理。
将 manifest.datasources 条目写成裸 ref 字符串条目必须是 ManifestDatasourceRef 对象:{ "name": "<ref>", "ref": "<ref>" }。裸字符串会导致下一条 dxs ng 命令(data generate、preview、push)中的 manifest 验证失败。
push 在 .../config/<ref>/lock 处因 DXS-API-TIMEOUT 失败(约 600 秒)不一定是卡住或 stale lock:在调试器下运行 API 的开发人员可能暂停在 lock/upsert 路径的断点处,或者 token 在调用过程中失效。请继续执行断点后的操作(或重新运行 dxs auth login),然后重试 push。
dxs ng data generate 留下了 $frontendFlows ref,或内嵌 componentRef selector 的 datasource 没有 mock keygenerator 不会为所有 key 生成初始值:$frontendFlows refs 完全不会生成;如果生成期间分支解析失败,它也会静默跳过 componentRef selector 对应的 datasource(不会报错)。生成后,请打开 mocks/harness-mocks.json,手动添加所有缺失的 key。
为 $frontendFlows ref 填入 mock 值,并期望预览使用该值$frontendFlows 会在 harness 中作为真实的、在客户端计算的代码运行——永远不会被 mock。预览始终显示 flow 实际计算的结果;针对 frontendFlow key 的 mock 条目不会生效。
全页面/仪表板 CAC 的 render.png 只显示了页面上半部分平台 shell 强制设置 html, body { overflow: hidden },因此 preview 的截图最多只覆盖一个 viewport(通常约为 569px)——无论内容多高,它都无法越过你自己的内部 overflow-y: auto 容器。这是平台 shell 的限制,并非布局错误。若要验证首个 viewport 之外的内容,请直接使用 agent-browser 访问 harness 提供服务的端口,并设置更高的 viewport,而不要只依赖 render.png。
使用 dxs source explore configs/trace 确认 CAC 是否存在或追踪其引用这两个命令都不会索引 type-36 组件——它们的 type filters 或输出中没有 CAC/customangularcomponent 类别。请使用 dxs ng list -b <branch> 确认组件是否存在;使用 dxs configuration get customangularcomponent <id> -b <branch> 或直接读取 manifest/harness source,追踪声明的 datasource/flow/componentRefs。
声明名为 refresh / $refreshEvent / outParamsChange 的 outParam 或 @Output,或者在 body 中重新声明两个生成的 @Output这些名称为保留名称——平台会在每个 CAC 上生成这些成员(这是 tab-content contract,使 CAC 能充当 hub/editor/card/dashboard tab);名称冲突会导致重复成员编译错误。例外情况是 body 中的 refresh() 方法——这是获准的覆盖方式;它会替换生成的默认实现(该默认实现会重新运行 ngOnInit)。
CAC 的价值在于定制化视觉效果——将预览截图视为验收测试,并在推送前使其与目标效果一致。

评论

支持 Markdown