优维低代码:Transform 数据转换

2023-11-06 12:59

本文主要是介绍优维低代码:Transform 数据转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

导语

优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。


连载第十七期

《高级指引:Transform 数据转换

在 Brick Next 中, dataSource+fields 是我们的开发者实践出来的不成文的约定,但是由于没有事先强制约定及深入调研,它的实现在不同的构件里虽然看起来相似,实际则各不相同,这给相关构件的下游使用者来说非常困惑,因此急需统一这些数据转换逻辑。

但由于 Storyboard 是声明式的,它并不擅长做逻辑处理,加上还有构件自行渲染构件并转换数据的场景,我们需要兼顾它们。

因此,我们提供了一套统一的数据转换 transform 模式,它同时用在 useResolves 和构件自行渲染构件并传递和转换数据的场景里。对于后者,我们提供统一的在容器构件中渲染子构件的 React Component: <BrickAsComponent>。

示例

例如 useResolves 里可以这样使用:

useResolves:  useProvider: "your.provider"  transform:    descriptions:      - label: "Username"        value: "@{name}"      - label: "Email"        value: "@{email}"

现在推荐使用 Evaluate Placeholders 求值占位符。

transform 是定义了 propertyName => propertyValue 的键值对,它定义了数据请求完成后,将以怎样的形式转换成 properties 输出到构件上。其中 @{...} 是和参数注入类似的占位符,关于它的更多信息,请查看本文下一节内容。

例如对于上述配置,假设 provider 提供的数据为:{ name: "Eve", email: "eve@example.com" },那么该构件将收到属性:​​​​​​​

properties:  descriptions:    - label: "Username"      value: "Eve"    - label: "Email"      value: "eve@example.com"

而在构件渲染子构件的地方也是类似处理。​​​​​​​

brick: "your.table-brick"properties:  columns:    - title: "User"      dataIndex: "name"      useBrick:        brick: "your.column-brick"        transform:          descriptions:            - label: "Username"              value: "@{cellData}"            - label: "Email"              value: "@{rowData.email}"

注意这里容器构件为单元格构件(columns)起到了类似 useResolves 的作用:为它们传递数据并提供转换数据的接口,在容器构件里可能是这样实现的:​​​​​​​

import { BrickAsComponent } from "@next-core/brick-kit";import { UseBrickConf } from "@next-core/brick-types";
class BrickTable() {  private renderColumn(useBrick: UseBrickConf, rowData, dataIndex) {    return (      <BrickAsComponent        useBrick={useBrick}        // 为子构件传递数据供 transform 使用        data={{          cellData: rowData[dataIndex],          rowData: rowData        }}      />    )  }  // ...}

注意:data 是容器给子构件传递的原始数据(例如表格构件可能需要给单元格构件同时灌入整个行的数据及单个字段的数据)。

# 接口定义​​​​​​​

interface ResolveConf {  useProvider?: string;  provider?: string;  method?: string;  args?: any[];  field?: string | string[];  name?: string;  // `transformFrom` 定义取原始数据的哪个字段(使用 `_.get(data, transformFrom)`),不填则为取整个原始数据。  transformFrom?: string | string[];  transform?: GeneralTransform;}
type GeneralTransform = string | TransformMap | TransformItem[];
interface TransformMap {  [propName: string]: any;}
interface TransformItem {  from?: string | string[];  to: string | TransformMap;  mapArray?: boolean | "auto";}
// `<BrickAsComponent />` 将统一完成子构件的渲染,包括数据转换、赋值属性、绑定事件。type UseBrickConf = UseSingleBrickConf | UseSingleBrickConf[];
interface UseSingleBrickConf {  brick: string;  properties?: Record<string, any>;  events?: BrickEventsMap;  transformFrom?: string | string[];  transform?: GeneralTransform;  if?: string | ResolveConf;  slots?: UseBrickSlotsConf;}
interface UseBrickSlotsConf {  [slotName: string]: UseBrickSlotConf;}
interface UseBrickSlotConf {  type?: "bricks";  bricks: UseSingleBrickConf[];}

# 占位符

@{ ... } 是 transform 使用的占位符。例如,对于 @{someField},解析得到的数据为 _.get(data, "someField"),因此,可以使用诸如 @{some[0].field} 来获得嵌套结构内的数据。另外,可以使用 @{} 来获得整个 data。

关于占位符的更多信息请查看 Placeholders 占位符。

注意:data 在 useResolves 中表示 provider 构件提供的数据,在  则为容器构件自行渲染子构件时传递的数据。

# 语法糖

为了简化一些常见场景的配置,我们提供了一些语法糖(也可以称为潜规则):

# 整个数据赋给单个属性

可以使用 transform: "plainString" 来实现直接将整个数据赋值给单个属性 plainString,此时 transform 等同于 useResolves[].name

数组数据源自动 Map

对于数据源是数组的,transform 会自动使用 Array.prototype.map() 来实现数组映射。例如对于以下配置:​​​​​​​

useResolves:  - useProvider: "your.provider"    transform:      tagList:        label: "@{name}"        value: "@{email}"

如果数据源返回的是:​​​​​​​

# Provider returns:- name: "Eve"  email: "eve@example.com"- name: "Wall E"  email: "wall-e@example.com"

那么构件得到的属性将是:​​​​​​​

properties:  tagList:    - label: "Eve"      value: "eve@example.com"    - label: "Wall E"      value: "wall-e@example.com"

# 高级

有时我们会需要转换混合了数组与普通类型的数据。例如对于提供分页能力的查询列表接口,除了处理数组类型的列表 list 外,还可能处理 page pageSize 等普通类型的数据,需要分别按需进行数组自动 map。这时我们可以使用数组形式的 transform 配置。

数组形式的 transform 配置可以按次序执行多次转换,例如对于以下配置:​​​​​​​

useResolves:  - useProvider: "your.provider"    transform:      - from: "list"        to:          tagList:            label: "@{name}"            value: "@{email}"      - from: "pageSize"        to: "pageSize"

以上配置对于 list 字段将进行数组自动 map,而 pageSize 则不会。另外可以额外指定 mapArray: false 以不进行数组自动映射。

这里的 from + to 的配置与 transformFrom + transform 的配置是类似的。

如果数据源返回的是:​​​​​​​

# Provider returns:list:  - name: "Eve"    email: "eve@example.com"  - name: "Wall E"    email: "wall-e@example.com"pageSize: 10

那么构件得到的属性将是:​​​​​​​

properties:  tagList:    - label: "Eve"      value: "eve@example.com"    - label: "Wall E"      value: "wall-e@example.com"  pageSize: 10

# 在 useBrick 中使用 slots

现在可以在 useBrick 中使用插槽 slots 了:​​​​​​​

brick: "basic-bricks.list-container"properties:  useBrick:    brick: "your.awesome-brick"    slots:      content:        bricks:          - brick: "your.another-brick"            transform:              textContent: "<% DATA.label %>"  data:    - label: "one"    - label: "two"

插槽配置和普通构件的插槽配置类似,区别是不能设置 type: "routes" 类型的插槽,并且 bricks 中每个子构件配置格式和普通 useBrick 一致,也可以消费和父级构件一样的数据源。

这篇关于优维低代码:Transform 数据转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/356770

相关文章

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Pandas统计每行数据中的空值的方法示例

《Pandas统计每行数据中的空值的方法示例》处理缺失数据(NaN值)是一个非常常见的问题,本文主要介绍了Pandas统计每行数据中的空值的方法示例,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是空值?为什么要统计空值?准备工作创建示例数据统计每行空值数量进一步分析www.chinasem.cn处

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映