地图作业平台低代码实战(搭建能力提升)

简介: 文章主要介绍了地图作业平台借助阿里低代码引擎,通过自定义插件,设置器,组件标准化等一系列方式,降低了作业平台内组件间联动,数据处理的难度,从而实现地图作业平台的可视化搭建

1.背景

  • 地图数据作业平台由大型的WebGIS"综合作业"逐步转换为人机结合,所见即所得的流水化"简单作业";

图1-1 综合作业与流水化作业

  • 流水化作业的特点是单一车间交互简单,但每个车间都有定制的业务逻辑(难以配置化实现,适合有扩展能力的低代码方式);
  • 作业平台低代码建设过程中,即使是任何一个简单作业车间也存在数据校验,组件联动,保存结果转换等逻辑(下图标牌场景车间为例);
  • 作业平台低代码的建设目标是让产品,工艺等非研发同学能独立搭建车间,因而要尽可能将逻辑操作可视化,少写或不写逻辑代码;
  • 非前端研发同学并不能很好的理解一些前端的基本概念:例如事件驱动,数据不可变 immutable原则, 数据双向绑定,组件(非)受控等;

2.问题与分析

2.1 一个简单的联动示例

图2-1 标牌场景判定车间

涉及组件: 7个

组件联动说明:初始化时第二、三个作业项置灰禁用;当前一个作业项选"否"时,激活下一个作业项;当前一个作业项选"是"时,之后的作业项清空;

问题: 对于这样一个最基础的组件间联动,低代码引擎的解决方案是WebIDE中绑定事件回调函数,在函数中通过写代码来实现逻辑。这样的方案对于前端研发来说,十几行代码很快就可以完成,但是对于非研发的同学(产品、工艺)等,他们需要理解事件驱动,数据不可变原则等,实现起来就非常困难,因此我们需要探索一个更加友好的方案:无须代码或一个表达式便可以实现以上联动功能。

2.2 示例中代码分析

// 以上示例的伪代码实现 classMainextendsPurComponents {
constructor() {
this.state= {
A: '',
B: '',
C: '',
  }
  }
// 响应逻辑handleAChange= (e) => {
// 1.数据源筛选const { target: { value } } =e;
// 2.双向绑定,组织数据结构letstateOptions= {
A: value;
    };
// 3.数据联动if (value==='1') {
stateOptions= {
...stateOptions,
B: '',
C: '',
      }
    } 
// 4.更新数据this.setState(stateOptions);
  };
// UI组件render() {
<divclassName="pic-wrapper"><PicPlayer.../></div><divclassName="task-oper"><Text>标牌是否是施工场景</Text><ButtonGrouponChange={(e) =>this.handleAChange(e)} />...<ButtonGroupdisabled={A!=='2'} .../>...<ButtonGroupdisabled={B!=='2'} .../></div>...blablabla  }
}
  • 由上方伪代码可以看到,一个车间的实现分为:UI + 逻辑
  • 在可视化搭建中,UI部分和简单交互由组件内部实现,跨组件的逻辑部分则由事件回调实现,回调函数可以拆分为以下四部分主体功能和相关概念:
  • 数据筛选: 从函数参数中筛选需要的数据(涉及事件驱动的概念)
  • 双向绑定: 受控组件由外部数据驱动,状态变化后需要更新依赖的数据源(受控组件,双向绑定,不可变原则)
  • 数据联动: 其它数据的更新,组件间的联动通信;(业务逻辑)
  • 数据更新: 前端框架Api;


2.3  示例中基本概念如何简化的思考

如何让非研发同学忽略前端的基本概念与语法,可视化的实现组件通信与联动,是降低可视化搭建难度的关键。为此,我们将函数主体的四个部分(数据筛选,双向绑定,业务逻辑联动,数据更新)分开来看:

  • 针对事件驱动中回调函数中的数据筛选能力,我们开发了数据筛选器,在设计页面的组件设置器中用树形结构静态声明函数参数,用户只需选择对应的参数即可实现类似数据解构和赋值的功能

图2-2 搭建页面中的数据筛器

  • 针对双向绑定,数据联动,immutable不可变原则,我们约定了简洁的数据存储语法,并针对此语法开发了特定的语法的解析插件,具体设计如下:
  • 页面中一个组件状态变化联动触发其它组件状态变化的场景,我们认为这是一个组件状态变化过程中的"副作用"(saveEffect);
  • 每一条"副作用"包含三部分,分别是源数据,目标数据,转换逻辑,以上面联动为例: 源数据A, 目标数据B, 转换逻辑是当A为1时,B清空, 对应数据结构是:
// 一个"副作用"对象由三部分构成{
// 源数据fromPath: 'e.target.value', 
// 目标数据toPath: 'state.B',
// 转换逻辑formatFunc: 'function switchStoreValue(value, state) { return A == '1' ? '' : state.B };'}
  • 我们在低代码组件中提供了saveEffect设置器,  让用户自行选择"副作用"的源数据、确定目标值,并书写转换逻辑,这部分逻辑被注入到组件中,组件在回调函数中将输出值 和 saveEffect 对象同时抛出,最终交由我们的语法解析插件解析并执行,实现组件联动;
  • 针对数据更新,我们认为用户根本无须关注框架层的API,所以开发了自动绑定设置器@ali/lowcode-setter-a-event-setter 会将组件的回调函数绑定到saveState全局函数中,在saveState全局函数中自动执行数据更新操作, 以下是一条联动"副作用"示例
// saveEffect 副作用对象的简单示例// 变更前全局数据state= {
temp: {
imageIndex: 0,
  },
workResult: {
imageList: [
      {
attr1: 1,
attr2: 2,
      },
...    ]
  }
}
// 用户确定的saveEffect对象{
// 源数据fromPath: 'value'// 1// 目标数据toPath: 'workResult.imageList[state.temp.imageIndex].activeKey';
// 默认值,用户无须书写formatFunc: 'function switchStoreValue(value, state) { return value }';
}
// 无转换逻辑,则经过插件解析后会生成以下结构并merge到state中{
temp: {
imageIndex: 0,
  },
workResult: {
imageList: [
      {
attr1: 1,
attr2: 2,
...activeKey:1      },
...   ]
  }
}

以上saveEffect对象,用户仅需指定目标值路径,插件会自动解析路径的语法,并将activeKey所有父级结构生成新的引用,最后自动调用setState实现组件更新;


图 2-3 插件将解析路径自动更新为新引用


3. 使用效果

3.1 一个线上车间的例子

使用saveEffect设置器节省代码的前后对比,以引导线内容车间为例,我们需要为一个引导线方向赋值一个属性,UI操作如下图,选中车道,更新车道的类型

图 3-1 更新车道属性


原生低代码引擎需要在页面JS中自行实现如下代码:

functionhandleButtonGroupClick(value) {
// 获取当前选中的箭头选项const { arrowList, currentIndex } =this.state;
constcurrentArrow=arrowList[currentIndex];
// 数据更新constnewArrow= {
...currentArrow,
type: value  };
// 数据不可变;constnewArrowList=arrowList.slice(0, currentIndex).concat([newArrow]).concat(arrowList.slice(currentIndex+1));
// lowcode API更新数据this.setState({
arrowList: newArrowList  });
}

使用saveEffect对象结合语法解析插件,使用者仅需在目标值中填写一句即可(大部分情况下转换函数是不用修改的);

state.arrowList[state.currentIndex].type=value

对应的setter UI 如下:

图3-2 setter设置器


3.2 procode组件如何接入saveEffect

了解saveEffect原理后,如果想将普通的ui组件接入saveEffect, 该如何改造, 改造成本是否很大?

图3-3 组件接入


由上图可以看到

  • 一个普通的组件是由userInterface 和 api驱动组件内部逻辑的运行;
  • saveEffect可以通过lowcode的setter层以api(props)的方式动态注入,然后在onChange等对外的接口中抛出即可,完全不影响组件的内部逻辑;
  • 组件抛出value和saveEffect后,系统会自动调用我们开发的解析插件进行数据解析和保存,从而实现组件间的"副作用"联动效果;

4. 总结与展望

这篇文章主要介绍了我们通过自定义插件,设置器,组件标准化等一些方式,降低了作业平台内组件间联动,数据处理的难度,实现了让非研发同学可以独立搭建我们小粒度车间的目标。除此之外,我们还在可视化方面开发了for循环组件if/else 等逻辑组件,意图用可视化组件的方式实现一些基本的模板语法,结合我们开发的车间模板,使得用户只需在页面内完成少量定制逻辑可以实现车间开发。

未来我们计划在低代码平台中加入逻辑编排能力,最终实现逻辑代码的图形化表达,进一步支持更为复杂的车间搭建。


5. 参考

《阿里低代码引擎》

《设置器扩展》

《setter开发调试》

《物料规范》

《阿里低代码引擎使用文档》

相关文章
|
7月前
|
机器学习/深度学习 编解码 人工智能
《深度解析:自注意力卷积神经网络的原理与卓越优势》
自注意力卷积神经网络融合了自注意力机制和卷积神经网络的优势,通过在特征图上动态分配注意力权重,捕捉长距离依赖关系。它不仅提升了局部特征提取能力,还能更好地理解全局结构与语义信息,在图像识别、自然语言处理等任务中表现出色。此外,该模型计算效率高、灵活性强、适应性广,并且易于扩展与其他技术结合,具有广泛的应用前景。
207 9
|
9月前
|
Ubuntu Linux Shell
/etc/rc.d/rc.local 的作用
/etc/rc.d/rc.local是Linux系统中的一个重要配置文件,其主要作用是在系统启动时执行特定的命令或脚本。以下是关于/etc/rc.d/rc.local的详细解释: ### 作用 * **系统启动任务配置**:该文件允许系统管理员或用户配置在系统启动时需要自动运行的任务。这些任务可以是启动服务、运行特定程序或执行脚本等。 * **开机自启动程序**:通过编辑/etc/rc.d/rc.local文件,用户可以自定义开机启动程序。只需将需要开机启动的程序命令或脚本路径添加到该文件中,并在系统启动时该文件将被自动执行。 ### 文件内容 * 通常包含一个shell脚本,该脚本在
634 12
|
定位技术 API
GIS开发:自定义坐标系的地图
GIS开发:自定义坐标系的地图
244 0
|
10月前
|
SQL 监控 数据可视化
完全开源!国内首个完全开源JAVA企业级低代码平台
JeeLowCode 是一款专为企业打造的 Java 企业级低代码开发平台,通过五大核心引擎(SQL、功能、模板、图表、切面)和四大服务体系(开发、设计、图表、模板),简化开发流程,降低技术门槛,提高研发效率。平台支持多端适配、国际化、丰富的组件库和灵活的布局设计,适用于 OA、ERP、IoT 等多种管理信息系统,帮助企业快速实现数字化转型。
完全开源!国内首个完全开源JAVA企业级低代码平台
|
数据采集 数据可视化 数据挖掘
爬虫技术对携程网旅游景点和酒店信息的数据挖掘和分析应用
爬虫技术是一种通过网络爬取目标网站的数据并进行分析的技术,它可以用于各种领域,如电子商务、社交媒体、新闻、教育等。本文将介绍如何使用爬虫技术对携程网旅游景点和酒店信息进行数据挖掘和分析,以及如何利用Selenium库和代理IP技术实现爬虫程序
1138 0
|
12月前
|
存储 弹性计算 缓存
阿里云服务器ECS通用型实例规格族特点、适用场景、指标数据解析
阿里云服务器ECS提供了多种通用型实例规格族,每种规格族都针对不同的计算需求、存储性能、网络吞吐量和安全特性进行了优化。以下是对存储增强通用型实例规格族g8ise、通用型实例规格族g8a、通用型实例规格族g8y、存储增强通用型实例规格族g7se、通用型实例规格族g7等所有通用型实例规格族的详细解析,包括它们的核心特点、适用场景、实例规格及具体指标数据,以供参考。
阿里云服务器ECS通用型实例规格族特点、适用场景、指标数据解析
|
Java Maven
解决Maven中CANNOT Resolve XXX错误
解决Maven中CANNOT Resolve XXX错误
1045 0
|
传感器 算法 API
HarmonyOS学习路之开发篇—设备管理(传感器开发)
HarmonyOS传感器是应用访问底层硬件传感器的一种设备抽象概念。开发者根据传感器提供的Sensor API,可以查询设备上的传感器,订阅传感器的数据,并根据传感器数据定制相应的算法,开发各类应用,比如指南针、运动健康、游戏等。
|
搜索推荐 前端开发 JavaScript
nextjs是怎么获得绝佳SEO的?
nextjs是怎么获得绝佳SEO的?
566 0
|
Java Android开发
设置Eclipse自带Ant指定版本JDK和运行时参数
设置Eclipse自带Ant指定版本JDK和运行时参数
528 0
设置Eclipse自带Ant指定版本JDK和运行时参数