尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
UI Grid 框架投影运行时(Framework Projection Runtime)规范详解:统一 Angular / React / Solid 适配器的插槽投影生命周期
前端UI组件【免费下载链接】ui-gridUI Grid: a Data Grid项目地址https://gitcode.com/gh_mirrors/ui/ui-grid点击查看免费下载本文深入解读 ui-grid 开源仓库中openspec/changes/consolidate-framework-adapter-runtime变更提案所定义的framework-projection-runtime规范。它描述了一套供 Angular、React、SolidJS 三个框架适配器共享的投影生命周期结构性插槽对账、插槽增删交付、投影上下文刷新、API 回调与基准协调、确定性拆除。读完本文你将掌握 ui-grid 的插槽命名约定、FrameworkSlotBridge的 add/remove 差分机制、三个 wrapper 当前各自实现投影的异同以及规范如何将它们收敛为一个由 vanilla 包统一拥有的可复用运行时。1. 规范背景为什么需要统一的投影运行时ui-grid 的三套框架 wrapperAngular、React、以及新合并的 SolidJS挂载的是同一个 vanilla 自定义元素ui-grid-element并通过其插槽桥接slot bridge投影框架自有的渲染内容。但在此之前每个 wrapper 都独立实现了以下几套编排逻辑选项options装配与传递插槽对账slot reconciliation投影上下文刷新context refreshAPI 包装API wrapping拆除清理teardown。正如proposal.md所述这种重复实现已经造成能力漂移capability drift并让第四个适配器的构建与验证成本变得不必要地高昂。规范的目标不是替换各框架的原生渲染能力而是把与框架无关的 DOM 插槽编排抽出来共享让 Angular 继续用 EmbeddedView、React 继续用 Portal、Solid 继续用其响应式 root但不再各自重写一套 DOM 生命周期。从源码结构看当前 vanilla 包 framework-slots.ts 已经提供了最底层的能力FrameworkSlotBridge在每次渲染后 diff 出added/removed增量并派发cellSlotsChanged等类型化事件ui-grid-standalone.element.ts 暴露setFrameworkRenderedSlots()来切换插槽占位渲染路径。本规范正是在这一既有桥接之上进一步统一谁监听、谁挂载、谁刷新、谁拆除的上层编排。2. 规范总览一个可复用的投影生命周期规范在Purpose中定义了核心目标提供一个可复用的投影生命周期使投影出的网格内容在各 UI 框架之间保持正确correct、高效efficient、可释放disposable。规范以 openspec 的需求 场景格式新增了5 条需求需求关键词核心约束Structural slot reconciliation结构性插槽对账仅在插槽配置发生结构性变化时才触发插槽布局重渲染插槽身份不变则保留已挂载的投影内容Projection lifecycle delivery投影生命周期交付新增插槽交付给框架渲染器移除插槽在 light-DOM 挂载点被丢弃前交付活跃插槽在 vanilla 元素移除前保持稳定身份Current projected contexts当前投影上下文排序/过滤/分组/分页/编辑/数据替换/虚拟化改变行、值、索引或插槽状态后刷新活跃投影上下文API callback and benchmark compatibilityAPI 回调与基准兼容组合 wrapper 与消费方提供的注册回调而不替换任何一方保持公开 API 形态基准完成后才汇报完成Deterministic teardown确定性拆除拆除时解绑事件与 API 监听、释放全部活跃投影、移除框架自有的 light-DOM 挂载点、忽略挂起的投影工作3. 需求一结构化插槽对账Structural slot reconciliation规范内容系统必须将框架声明的插槽配置与vanilla 网格元素进行对账并且只在该配置发生结构性变化时才请求插槽布局重渲染。当插槽身份保持不变时必须保留已挂载的投影内容。这一需求对应两个场景仅数据更新时保留已投影单元格当 wrapper 替换数据、而某个可见投影单元格保持相同插槽身份时该单元格继续挂载并接收到最新上下文。渲染器列被移除时当 wrapper 从声明的投影插槽集合中移除某列时系统必须销毁该列的投影内容并在后续渲染中恢复 vanilla 字符串渲染路径。3.1 源码对照configure()的结构变化判定现有 framework-slots.ts 的configure()方法正是这条需求的现状雏形它把新配置与当前标记集合做Set比较任何cells/headers/filters集合或groupRow/expandableRow/emptyState布尔值的差异都会返回truestructureChanged表示需要一次结构重渲染否则返回false视为 no-op。元素侧 setFrameworkRenderedSlots() 在收到true时强制进行一次结构重渲染并清空lastRowStateFingerprints——注释明确说明原因单元格外壳内容取决于hasCell()/hasHeader()等标记值而这些值并未被行级指纹捕获。这就保证了同一插槽身份的数据更新不会触发结构重渲染列增删才会。3.2 数据更新不破坏投影的工程细节vamilla 渲染路径有一个容易踩坑的细节当行的指纹与上次渲染一致时patch快速路径会跳过该行的渲染若此时flush()直接拿 pending 与 last 做 diff就会把未重新登记的单元格误判为removed从而摧毁框架 wrapper 已投影的内容。为此FrameworkSlotBridge提供 carryRowCells()把上一轮该行已知的单元格插槽携带进当前 pending 集合该调用发生在 patch.ts。而纯数据更新的场景下则走 mergePendingIntoLast()将新上下文合并进 last 集合而不派发任何事件——因为结构没有变化只有单元格上下文刷新了。4. 需求二投影生命周期交付Projection lifecycle delivery规范内容系统必须把新增插槽交付给框架渲染器必须在对应 light-DOM 挂载点被丢弃之前交付移除插槽并且活跃插槽的身份要保持稳定直到 vanilla 元素将其移除。其典型场景是虚拟化行离开视口当 vanilla 网格在虚拟化过程中移除一个已投影的行插槽时框架渲染器恰好收到一次针对该插槽的移除通知从而可以释放框架自有的视图或 root。4.1 插槽命名约定与类型化增量framework-slots.ts头部的注释明确定义了插槽命名约定这也是投影身份的稳定基础cell-columnName-rowId—— 每行每列一个header-columnName—— 每列单例filter-columnName—— 每列单例group-row-groupId—— 每个分组expandable-row-rowId—— 每行empty—— 单例。FrameworkSlotDeltaTSlot以{ added, removed }形式承载每个插槽族的变更flush()framework-slots.ts在每次渲染结束时对六种插槽逐一 diff 并派发cellSlotsChanged、headerSlotsChanged、filterSlotsChanged、groupRowSlotsChanged、expandableRowSlotsChanged、emptyStateSlotChanged事件。disconnectedCallback中调用 flushRemovals() 让所有剩余插槽以removed形式交付——这正是移除先于挂载点丢弃的既有实现。4.2 虚拟化滚动下的生命周期虚拟化快速路径 renderVirtualBody() 只替换.grid-virtual-body的 innerHTML 并在末尾调用frameworkSlots.flush()。滚出视口的行对应的cell-col-rowId插槽从 pending 中消失于是差分结果为removedwrapper 收到单次移除并可销毁对应视图。规范要求运行时把这一机制统一为每个插槽族的类型化生命周期让 Solid 的 root、React 的 portal、Angular 的 EmbeddedView 都能在同一契约下处置。5. 需求三当前投影上下文刷新Current projected contexts规范内容当排序、过滤、分组、分页、编辑、数据替换或虚拟化改变了活跃投影内容所代表的行、值、索引或插槽状态时系统必须在一次完整的网格渲染完成后刷新活跃投影上下文。这条需求要解决一个根本局限插槽 delta 事件无法表达仅上下文变化的更新。design.md 明确指出deltas alone do not identify every context-only update。两个场景说明了边界排序保留插槽名排序改变了占据某个既有投影单元格插槽的可见行但没有产生插槽 add/remove 增量——投影单元格仍须收到排序渲染完成后的行、值与行索引。编辑更新展开详情某行带有活跃投影详情detail时提交一次编辑——详情须收到该行提交后的值而不必触发一次无关的网格更新。5.1 现有 wrapper 如何自行处理上下文刷新由于 vanilla delta 事件覆盖不到上下文更新三个 wrapper 现在各自想办法React在 UiGrid.tsx 中用useEffect([options.data])监听数据变化按rowId重建MaprowId, row对每个已挂载插槽重新计算value并setSlots(nextSlots)再通过 Portal 重新渲染。Angular在 ui-grid.component.ts 的updateSlotViewContexts()中更新EmbeddedViewRef的$implicit/value/row上下文并把多个视图的detectChanges()批量放进一次NgZone.run()注释特别说明这是为避免虚拟化滚动时每帧触发数百次同步变更检测。Solid在 cellRenderers.ts 的refresh()中通过api.core.getVisibleRows()获取当前可见行重新计算 value 并调用entry.update(context)UiGrid.tsx的wrapApi()还为refresh、setFilter、sortColumn等 API 操作包上refreshAfter()保证操作后刷新。5.2 规范方案post-render 投影同步边界design.md 的第四项决策提出vanilla 元素在 DOM patch 与 framework-slot flush 之后暴露一个投影渲染完成通知projection-render completion notification。运行时将该信号合并coalesce然后从当前 API/options 状态读取活跃描述符再要求驱动driver更新。该信号仅在配置了框架投影时才发出刷新工作按渲染批次合并执行。这补上了 delta 事件表达不了的排序后同一插槽换行、编辑后详情更新等场景。6. 需求四API 回调与基准兼容API callback and benchmark compatibility规范内容系统必须组合composewrapper 自有与消费方提供的 API 注册回调而不是用一方替换另一方必须保持公开网格 API 形态并且必须在所需的投影渲染**安定settled**之后才报告基准完成。两个场景两个注册回调同时存在当 wrapper 回调与options.onRegisterApi都提供了时二者都收到同一个注册对应的兼容 API。基准包含投影渲染当基准在带有活跃框架投影的网格上运行时其结果必须在框架完成该轮基准迭代触发的渲染工作之后才交付。6.1 现有实现的回调组合方式三个 wrapper 当前都已经在做回调组合React applyOptions() 中onRegisterApi先调用onRegisterApiRef.current?.(wrappedApi)再调用opts.onRegisterApi?.(wrappedApi)Angular applyOptions() 同时emit(apiReady)并调用opts.onRegisterApiSolid registerApi() 会把 wrapped API 分发给 cell/header/detail/editor 四个 bridge再调用props.onRegisterApi与props.options.onRegisterApi。6.2 基准完成等待投影渲染三个 wrapper 都重写了core.benchmark把每次迭代等待投影渲染安定内嵌进去React 通过waitForScheduledWrapperRender()与useLayoutEffect中的版本计数等待 scheduled wrapper render 完成UiGrid.tsxAngular 每次迭代后await Promise.resolve()再继续ui-grid.component.tsSolid 每次迭代后调用各 bridge 的refresh()并await Promise.resolve()UiGrid.tsx。规范将这三种机制统一抽象为驱动提供的view settled承诺React 等待 commit、Angular 等待批量的变更检测、Solid 等待其调度渲染工作从而既保持单一公开 API 外观又把框架调度留在了框架本地。7. 需求五确定性拆除Deterministic teardown规范内容wrapper 或网格拆除后系统必须解绑元素与 API 监听、释放所有活跃投影内容、移除框架自有的 light-DOM 挂载点并忽略挂起的投影工作。关键场景是延迟挂载期间卸载当 wrapper 在延迟的元素或编辑器投影工作执行前卸载时拆除后不得再挂载任何投影内容也不得残留任何监听器或框架 root。7.1 现有拆除路径vanilla 元素disconnectedCallback中依次unsubscribe、断开模板观察器、取消 rAF 帧、置空基准处理器、flushRemovals()派发全部移除事件ui-grid-standalone.element.ts。Reactmount effect 的 cleanup 设置disposed true、解绑cellSlotsChanged、移除元素、清空 slots 状态并在卸载createWrappedGridApi时取消底层基准订阅UiGrid.tsx。AngularngOnDestroy调用destroyAllSlotViews()appRef.detachViewview.destroy()并移除[slot]节点、解绑基准订阅与事件监听、移除元素ui-grid.component.ts。SolidonCleanup置disposed true、逐桥 dispose、清空基准监听、移除元素UiGrid.tsx。规范把这些散布在各 wrapper 的清理逻辑收敛到运行时并显式要求忽略挂起的投影工作——例如 Solid 的configureVersion微任务校验if (disposed || version ! configureVersion) return这种异步竞态防护将成为运行时统一的默认行为。8. 设计决策共享运行时放在哪里、如何分层design.md 记录了五项关键决策直接决定了规范的实现形态共享运行时放在 vanilla 包新增ornery/ui-grid-vanilla的一个 DOM 面向 helper 子路径而不是第四个子包。理由它依赖具体自定义元素契约及其插槽事件且已是每个 wrapper 的既有依赖可避免新包、新版本与构建顺序问题。其模块初始化不得访问浏览器全局对象SSR 敏感的 wrapper 继续只在客户端生命周期中加载 DOM 行为。编排与渲染分离运行时负责请求的插槽配置、事件监听、稳定插槽记录、light-DOM 挂载点、API 注册组合、刷新合并与释放框架提供的**投影驱动projection driver**负责创建、更新、释放某个插槽的框架自有内容。这保留了 Angular 原生变更检测、React commit 与 Solid 所有权而不是在它们之上再做一层渲染抽象。类型化插槽族 单一驱动形态cell / header / detail / filter / group / empty-state 作为类型化家族运行时统一其 add/remove 生命周期各框架驱动只声明支持的家族。这样 React 与 Angular 可先迁移现有 cell 支持Solid 保留其额外能力未来 wrapper 渐进接入。post-render 投影同步边界如前文需求三所述。集中 API 与基准协调运行时组合onRegisterApi回调并接管底层基准订阅的替换驱动提供 view settled 承诺。9. 迁移计划与风险权衡tasks.md 将实施拆为四个阶段基线与会约构建 cells/headers/details/editors/filters/empty state/SSR-hydration/virtualization/benchmark/teardown 的 wrapper 奇偶校验矩阵在支持的 Node 版本上复现并解决 Solid hydration 基线验证npm run build:solid npm run test:solid定义类型化投影驱动与插槽族接口要求 TypeScript 拒绝不兼容的插槽/上下文配对。共享 vanilla 运行时添加副作用无关的子路径与公开类型导出验证消费方构建在未定义自定义元素时也能 import实现结构化插槽对账、挂载点归属与监听清理实现 post-render 同步边界与合并的活跃上下文刷新实现共享 API 注册与基准协调为每个插槽族、虚拟化移除、异步取消与拆除添加 conformance 测试。Wrapper 迁移React cell portals 迁入共享运行时不改UiGridpropsAngular 模板 cell 投影迁移不改app-ui-grid输入输出Solid cell/header/detail/editor bridge 迁移到投影驱动仅删除被共享运行时取代的 wrapper 本地编排。奇偶校验与发布验证三框架共用同一场景矩阵决定并记录 React/Angular 的 header/detail/editor/filter/group/empty 支持顺序——不支持的家族要可预测地失败而不是静默渲染过期内容运行npm run test:angular、npm run test:react、npm run test:vanilla、npm run test:solid及按依赖顺序的包构建。风险与权衡design.md 第五节给出了四条防护驱动保持小巧、类型化并在各 wrapper 内直接单测运行时单独测试post-render 刷新按完成渲染合并、只刷新被渲染视口界定的活跃插槽vanilla 子路径保持导入时无副作用、DOM 操作只进客户端生命周期钩子增量迁移期间以奇偶校验矩阵约束一个 wrapper 一个 wrapper 地迁移。回滚被限制为回退单个 wrapper 的迁移——直到迁移完成前现有 wrapper 本地桥接仍可用。10. 如何验证与进一步阅读规范从设计到落地可以通过以下仓库文件追踪规范本体framework-projection-runtime/spec.md、动机与能力清单见 proposal.md、设计决策见 design.md、任务分解见 tasks.md。现状插槽桥接vanilla 包 framework-slots.ts 与 ui-grid-standalone.element.tssetFrameworkRenderedSlots、frameworkSlots.flush()集成点以及 patch.ts 中的carryRowCells/mergePendingIntoLast快速路径。三框架现状实现React wrapperportal benchmark 等待、Angular wrapperEmbeddedView 批量变更检测、Solid wrapper 与 cellRenderers.ts响应式 root refresh 桥。架构说明vanilla 包 AGENTS.md 的 Framework Slot System 一节描述了当前setFrameworkRenderedSlots → slot placeholder → flush → 事件 → wrapper 挂载的四步工作流可作为理解规范的入口。需要说明的是本文所解析的 spec 属于 openspec spec-driven 变更提案其 tasks 清单尚未勾选即共享运行时属于计划中的架构演进而非已落地代码文中标注的源码均来自迁移前的现有实现用于印证规范所描述的问题与既有机制。赞分享前端UI组件【免费下载链接】ui-gridUI Grid: a Data Grid项目地址https://gitcode.com/gh_mirrors/ui/ui-grid点击查看免费下载相关推荐Frosted Glass Lite 主题树莓派仪表盘帧率从 15 提到 30 FPS 的方法Frosted Glass Lite 主题树莓派仪表盘帧率从 15 提到 30 FPS 的方法 周日晚你在树莓派 4B 上打开 Home Assistant前端UI组件Elsa User Tasks 运行时契约解析身份中立、书签投影与任务生命周期编排Elsa User Tasks 运行时契约解析身份中立、书签投影与任务生命周期编排 本文围绕 ElsaThe Workflow Engine for .NE后端工作流自动化流程编排低代码Open Interpreter Windows完整安装指南4步让开源代码智能体跑进终端Open Interpreter Windows完整安装指南4步让开源代码智能体跑进终端 Open Interpreter 是一个面向 Kimi K3、GLM人工智能大模型AI Agent代码智能体AI 应用CLI上一篇FastRTC用户行为分析案例基于实时数据的用户研究下一篇终极指南如何使用OpenCore Legacy Patcher让老款Intel Mac重获新生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Loop Engineering实战:用循环提示工程构建AI内容质量闭环

Loop Engineering实战:用循环提示工程构建AI内容质量闭环

1. 为什么说Loop Engineering不只是“多问几遍”:核心价值拆解1.1 从单次对话到工程闭环:一个概念的重新定义先说结论:**Loop Engineering(循环提示工程)不是让你对着模型反复说“再想想”,而是一套有结构、…

📅 2026/10/13 6:07:23
微信小程序4S店管理系统源码解析与部署实战

微信小程序4S店管理系统源码解析与部署实战

简介:微信小程序4s店管理系统源码数据库.zip 面向汽车4S店信息化管理场景,也适合计算机相关专业毕业设计使用。系统覆盖客户管理、车辆管理、销售管理、售后服务、库存管理等核心模块,完整包含前端小程序展示逻辑与后端数据存储处理&#xff…

📅 2026/10/13 6:07:23
SWIG 4.0.2 Windows安装与C/C++到Python绑定实战

SWIG 4.0.2 Windows安装与C/C++到Python绑定实战

简介:swig-4.0.2-windows版本安装包是SWIG 4.0.2针对Windows平台的预编译发行包,面向需要为C/C库生成Python、Java、Go、Ruby等语言接口的开发者。解压后将swigwin路径加入PATH即可在命令行调用swig,配合.i接口文件自动生成目标语言绑定代码。…

📅 2026/10/13 6:07:23
MORE NEWS

更多资讯

📰

职场心理博弈漫画创作指南

1. 职场心理博弈的漫画化表达这个标题描述了一个极具戏剧性的职场场景:一位长期被领导打压的员工在获得年终奖后立即辞职,而领导却以"为你好"为由试图道德绑架。这种强烈的冲突感非常适合用漫画形式表现,既能突出黑色幽默&#xff…

📰

华为OD机试真题精讲:机场航班调度程序(Python/Java/C++多语言实现)

华为OD机试真题精讲:机场航班调度程序(Python/Java/C++多语言实现) 一、题目描述(2025B卷高频100分题) 机场需要对进出港航班进行最优调度,以最大化单日可处理的航班总数,规则如下: 输入为: 跑道数量runway_num(正整数,每条跑道同一时间只能处理一架航班); 航班…

📰

Archify:架构即代码的开源实践与商业化路径

1. 项目概述:一个开源工具如何引爆商业化想象 “我免费开源的 Archify 约 8 万 Star,别人先做出了 $19/月的在线版”——这句话不是抱怨,也不是营销话术,而是一线开发者在真实世界里反复遭遇的典型张力现场。Archify 这个名字本身…

📰

多智能体协作新范式:基于信息素网络的去中心化上下文管理

1. 为什么智能体需要一套“信息素网络”来管理上下文做过智能体(Agent)开发的人都有一个共同体会:单个智能体跑一个简单任务时,上下文管理不是问题,把历史对话往提示词里一塞就完事了。可一旦系统里同时跑着十几个甚至…

📰

用分形几何驯服AI音乐:一场数学建模专家的实测手记

搞了几十年数学建模,平时跟AI打交道就是让它算积分、解偏微分方程。结果这两天被朋友拉进一场争论里:OpenAI那边的AI生成音乐又说自己「接近人类创作水准」,评论区吵翻天了。我懒得打嘴仗,跑去跟Opus 5.5较劲了一个周末&#xff0…

📰

租房数据采集与可视化平台:Python爬虫+Flask+Layui+ECharts实战

最近好几个准备做毕设的同学来找我聊选题,翻来覆去总绕不开"XX管理系统""XX商城"这类做了几百遍的东西,答辩时很难讲出新意。我一般会建议换个思路:做一个租房市场数据采集与可视化平台——用Python写爬虫把房源数据抓下…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬