AdminJS flat.get 完全指南:从扁平化 params 中安全提取嵌套属性

发布时间:2026/9/25 14:03:10

AdminJS flat.get 完全指南:从扁平化 params 中安全提取嵌套属性 后端低代码【免费下载链接】adminjsAdminJS is an admin panel for apps written in node.js项目地址https://gitcode.com/gh_mirrors/ad/adminjs点击查看免费下载本文聚焦 AdminJS 数据模型的核心机制——扁平化flatten存储深入讲解flat.get()工具函数的完整用法、底层实现原理含includeAllSiblings选项与数组兄弟节点处理以及它在BaseRecord、前端组件和参数预处理中的实际应用帮助你准确、安全地从扁平化 params 中提取任意层级的嵌套数据。为什么 AdminJS 需要 flat.get扁平化数据模型Flatten ParamsAdminJS 在后端把所有来自数据库表/集合的数据存入BaseRecord的params对象中通常是一个{key: value}结构在前端则对应RecordJSON.params。简单情况下它长这样params: { name: John, surname: Doe, age: 28, }但在真实业务中数据库往往存在嵌套的 JSONB 属性或 Mixed Schema开发者还会向前端/后端发送数组等复杂结构。因此 AdminJS 采用“扁平化”方案在保存到params之前把嵌套对象与数组全部拍平用.分隔路径分隔符定义在 src/utils/flat/constants.ts值为.params: { name: John, surname: Doe, age: 28, // nested objects auth.facebook: some login token, auth.twitter: twitter login token, // arrays interests.0: running, interests.1: jogging, }为什么要拍平两条硬核理由数据库局部更新若直接保存整个原始对象Model.save({ auth: { facebook: newFacebookToken } })ORM 会整体覆盖auth字段从而丢失auth.twitter而保存扁平形式Model.save({ auth.facebook: newFacebookToken })则可保留同层其他键值。这一点在 Mongoose 适配器最擅长处理 mixed values中体现得最明显。前后端 FormData 传输AdminJS 支持前端上传文件到后端最优方式是使用 FormData它要求所有字段值为[key: string]: string形式恰好与扁平化 params 完美契合。正因为如此BaseRecord与RecordJSON中你拿到的都不是原始对象而是扁平版本此时就需要flat模块提供的一组辅助函数详见 src/utils/flat/flat.doc.md。flat.get 函数签名与基本用法flat.get在 src/utils/flat/get.ts 中实现并通过 src/utils/flat/flat-module.ts 挂载到flat命名空间导出flat模块自 AdminJS 3.3 版本引入。类型定义位于 src/utils/flat/flat.types.tsconst get (params: FlattenParams {}, propertyPath?: string, options?: GetOptions): any参数说明参数类型必填说明paramsFlattenParams是有默认值{}扁平化参数对象键为路径字符串值为基本类型、Date、null、空数组、空对象或FilepropertyPathstring否要提取的属性路径如education.school不传则返回整个反扁平化unflatten对象optionsGetOptions否可选配置目前仅含includeAllSiblingsFlattenValue支持的类型联合见 src/utils/flat/flat.types.tsstring、boolean、number、Date、null、[]空数组、{}空对象以及File。基础示例原文档给出的典型场景src/utils/flat/get.doc.mdimport flat from adminjs const params { name: John, education.school.name: Harvard, education.school.id: 123, } const data flat.get(params, education.school) // results to { // name: Harvard, // id: 123, // } // 不传 propertyPath 时返回整个反扁平化对象 const data flat.get(params) // results to { // name: John, // education: { // school: { // name: Harvard, // id: 123, // } // } // }注意flat.get(params)内部直接调用flat.unflatten(params)get.ts即“取出全部并还原为嵌套对象”flat.unflatten与flat.flatten一样直接来自 npmflat包见 flat-module.ts。查找规则先精确匹配再前缀匹配flat.get的查找策略分两步get.ts精确命中优先若params中已存在与propertyPath完全相等的键则直接返回params[propertyPath]。源码特意注释说明不能用typeof params[propertyPath] ! undefined判断因为属性值本身可能是undefined那样会误返回[undefined]。前缀匹配兜底未精确命中时通过propertyKeyRegexsrc/utils/flat/property-key-regex.ts构造正则再用selectParamssrc/utils/flat/select-params.ts筛出所有以该路径开头的扁平键把它们改写到临时键TEMP_HOLDING_KEY下最后整体unflatten并取出该临时键对应的值。若没有任何匹配键返回undefined。propertyKeyRegex生成的匹配模式形如^path($|\.)保证只匹配“以 path 为完整路径段开头”的键因此flat.get(params, interest.Of)不会误命中interest.OfMe.0这一点有专门测试用例验证见 get.spec.ts。边界行为一览以测试用例为准src/utils/flat/get.spec.ts 用一组完整用例界定了flat.get的边界行为普通标量get(params, name)直接返回该值不存在的属性返回undefined例如get(params, nameNotExisting)值为undefined的属性同样返回undefined嵌套数组get(params, interest.OfMe)还原出[javascript, typescript, brainTumor]嵌套对象含数组get(params, interest)还原出{ OfMe: [...] }null值get(params, nulled)返回nullnull属于合法FlattenValue不会被吞掉多级嵌套数组get(params, nested.0.el)得到[{ value: val0.0 }, { value: val0.1 }]。includeAllSiblings跨兄弟节点提取数组元素问题场景当属性路径中只给出一个数组索引、但期望提取所有兄弟索引的数据时普通前缀匹配是不够的。假设扁平键为nested.0.el.0.value / nested.0.el.1.value nested.1.el.0.value / nested.1.el.1.value如果调用get(params, nested.el)它只会命中nested与el之间的固定分隔符无法覆盖nested.0.el与nested.1.el两组数据。GetOptions.includeAllSiblings正是为此设计类型注释见 src/utils/flat/flat.types.ts。底层处理开启includeAllSiblings后propertyKeyRegex会把路径中的每个.替换为(\.|\.\d\.)即“普通分隔符或带索引的分隔符”从而让nested.el同时匹配nested.0.el、nested.1.el见 property-key-regex.ts。在 get.ts 中因为不同兄弟节点内部存在相同的子索引如两处都有.0.value直接 unflatten 会导致键冲突因此源码按枚举顺序把索引重写为连续编号nested.0.el.0.value、nested.0.el.1.value、nested.1.el.0.value、nested.1.el.1.value分别变为TEMP_HOLDING_KEY.0.value、.1.value、.2.value、.3.value再统一还原。最终flat.get(params, nested.el, { includeAllSiblings: true }) // 返回 [ { value: val0.0 }, { value: val0.1 }, // { value: val1 }, { value: val2 } ]该行为由测试用例 get.spec.ts 验证另外处理嵌套引用 ID 的用例get.spec.ts表明对于Skills.hardSkills.0.Profession这类嵌套引用flat.get(params, Skills.hardSkills.Profession, { includeAllSiblings: true })会返回[referenceId]这正是从扁平数据中批量收集引用字段的标准姿势。在 AdminJS 中的实际调用点1. BaseRecord 的取值入口src/backend/adapters/record/base-record.ts 中BaseRecord#get(propertyPath?, options?)直接透传flat.get(this.params, propertyPath, options)其 JSDoc 示例明确说明当params { genre.0: male, genre.1: female }时get(genre)返回[male, female]。因此所有基于BaseRecord的属性读取本质上都由flat.get完成。同文件中旧的param(path)方法已标记 deprecated也调用flat.get(this.params, path)base-record.ts。2. 前端属性型组件flat.get(record.params, property.path)是前端渲染扁平数据的事实标准例如数组型属性的编辑/列表/展示组件edit.tsx、list.tsx、show.tsx 均用flat.get(record.params, property.path) || []兜底空数组Key-Value 型属性edit.tsx 与 show.tsx 用?? {}兜底空对象引用型属性reference/edit.tsx 用flat.get(record?.params, property.path)提取引用 ID。3. 参数预处理src/utils/param-converter/prepare-params.ts 在把请求参数转换给后端属性时通过flat.get(params, property.path())读取对应属性的值保证嵌套字段在前后端之间流转时保持一致。使用建议与注意事项不传propertyPath即整体还原代价是返回整个嵌套对象数据量大时注意性能与内存优先让includeAllSiblings与数组型属性配合当属性路径中间存在索引段如nested.el对应nested.0.el、nested.1.el时务必开启否则取不到数据null、空数组、空对象会被原样返回可用?? {}或|| []按需兜底避免渲染报错值为undefined的属性返回undefined与“键不存在”行为一致判断时无需区分。延伸阅读flat模块整体说明与数据模型背景src/utils/flat/flat.doc.md配套辅助函数set.ts写入、remove-path.ts删除路径、select-params.ts筛选前缀参数、path-to-parts.ts路径切分、merge.ts合并实现与测试get.ts、get.spec.ts赞分享后端低代码【免费下载链接】adminjsAdminJS is an admin panel for apps written in node.js项目地址https://gitcode.com/gh_mirrors/ad/adminjs点击查看免费下载相关推荐OBS源录制插件怎么用一个过滤器让每个画面单独出片OBS源录制插件怎么用一个过滤器让每个画面单独出片 你是不是也遇到过这样的尴尬OBS里排好的场景里摄像头和游戏画面挤在同一个视频里想单独剪一条摄像头素材后端低代码Buzz揭秘开源离线音频转录引擎的架构设计与技术实现Buzz揭秘开源离线音频转录引擎的架构设计与技术实现 Buzz 是一款基于 OpenAI Whisper 的离线音频转录与翻译工具为开发者提供了完全本地化的后端低代码RxJS 4 pluck 操作符完全指南从嵌套对象中安全提取属性值RxJS 4 pluck 操作符完全指南从嵌套对象中安全提取属性值 导读 pluck 是 RxJSReactive Extensions for JavaS后端上一篇PiliPlus解锁B站无限可能打造你的专属视频体验终极方案下一篇TrafficMonitor插件终极指南如何在Windows任务栏轻松监控系统性能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/25 18:13:22

OpenMontage:首个本地化AI视频Agent工作流实战指南

1. 这不是“AI剪视频”,而是第一次看到Agent真正接管整条工作流最近在几个技术群和本地AI开发者聚会上,总有人问:“AI Agent真能自己做完一条视频?”语气里带着三分期待、七分怀疑——毕竟过去两年,我们见惯了“AI生成…

2026/9/25 18:13:22

【领域篇06】效能评估在金融科技与风控领域的应用实践

目录 一、引言 二、效能评估的基本概念与价值 三、金融科技领域的效能评估应用 3.1 系统性能评估 3.2 算法模型效能评估 3.3 业务流程效能评估 四、风控领域的效能评估实践 4.1 风控模型效能评估 4.2 反欺诈效能评估 4.3 贷后管理效能评估 五、效能评估的实施路径 …

2026/9/25 18:08:22

YOLOv8实战指南:从环境搭建到边缘部署的完整流程

1. 为什么我最终选择了ultralytics这套方案第一次接触YOLOv8是在一个工业质检的小项目上,当时的需求很明确:在产线边缘设备上跑一个目标检测模型,识别零件表面的缺陷。团队之前用的是YOLOv5,代码维护得比较乱,训练脚本…

2026/9/24 20:24:47

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/25 0:02:35

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:02:35

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:02:35

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑