关于java:地图作业平台低代码实战搭建能力提升

82次阅读

共计 3817 个字符,预计需要花费 10 分钟才能阅读完成。

背景

1、地图数据作业平台由大型的 WebGIS” 综合作业 ” 逐渐转换为人机联合,所见即所得的流水化 ” 简略作业 ”;

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

2、流水化作业的特点是繁多车间交互简略,但每个车间都有定制的业务逻辑(难以配置化实现,适宜有扩大能力的低代码形式);

3、作业平台低代码建设过程中,即便是任何一个简略作业车间也存在数据校验,组件联动,保留后果转换等逻辑(下图标牌场景车间为例);

4、作业平台低代码的建设指标是让产品,工艺等非研发同学能独立搭建车间,因此要尽可能将逻辑操作可视化,少写或不写逻辑代码;

5、非前端研发同学并不能很好地了解一些前端的基本概念:例如事件驱动,数据不可变 immutable 准则,数据双向绑定,组件(非)受控等;

问题与剖析

一个简略的联动示例

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

波及组件: 7 个

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

问题: 对于这样一个最根底的组件间联动,低代码引擎的解决方案是 WebIDE 中绑定事件回调函数,在函数中通过写代码来实现逻辑。这样的计划对于前端研发来说,十几行代码很快就能够实现,然而对于非研发的同学(产品、工艺)等,他们须要了解事件驱动,数据不可变准则等,实现起来就十分艰难,因而咱们须要摸索一个更加敌对的计划:毋庸代码或一个表达式便能够实现以上联动性能。

示例中代码剖析

// 以上示例的伪代码实现 

class Main extends PurComponents {constructor() {
    this.state = {
      A: '',
      B: '',
      C: '',
    }
  }

  // 响应逻辑
  handleAChange = (e) => {
    // 1. 数据源筛选
    const {target: { value} } = e;
    // 2. 双向绑定,组织数据结构
    let stateOptions = {A: value;};

    // 3. 数据联动
    if (value === '1') {
      stateOptions = {
         ...stateOptions,
        B: '',
        C: '',
      }
    } 
    // 4. 更新数据
    this.setState(stateOptions);
  };

  // UI 组件
  render() {
    <div className="pic-wrapper">
      <PicPlayer ... />
    </div>
    <div className="task-oper">
      <Text> 标牌是否是施工场景 </Text>
      <ButtonGroup onChange={(e) => this.handleAChange(e)} />
      ...
      <ButtonGroup disabled={A !== '2'} ... />
      ...
      <ButtonGroup disabled={B !== '2'} ... />
    </div>
    ... bla bla bla
  }
}
  • 由上方伪代码能够看到,一个车间的实现分为:UI + 逻辑
  • 在可视化搭建中,UI 局部和简略交互由组件外部实现,跨组件的逻辑局部则由事件回调实现,回调函数能够拆分为以下 四局部主体性能和相干概念:
  • 数据筛选:从函数参数中筛选须要的数据(波及事件驱动的概念)
  • 双向绑定:受控组件由内部数据驱动,状态变动后须要更新依赖的数据源(受控组件,双向绑定,不可变准则)
  • 数据联动:其它数据的更新,组件间的联动通信;(业务逻辑)
  • 数据更新:前端框架 Api;

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

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

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

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

  • 针对双向绑定,数据联动,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-2 插件将解析门路自动更新为新援用

应用成果

一个线上车间的例子

应用 saveEffect 设置器节俭代码的前后比照,以疏导线内容车间为例,咱们须要为一个疏导线方向赋值一个属性,UI 操作如下图,选中车道,更新车道的类型

图 3-1 更新车道属性

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

function handleButtonGroupClick(value) {

  // 获取以后选中的箭头选项

  const {arrowList, currentIndex} = this.state;

  const currentArrow = arrowList[currentIndex];

  // 数据更新

  const newArrow = {

    ...currentArrow,

    type: value

  };

  // 数据不可变;const newArrowList = 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 如下:

procode 组件如何接入 saveEffect

理解 saveEffect 原理后,如果想将一般的 ui 组件接入 saveEffect, 该如何革新, 革新老本是否很大?

由上图能够看到

  • 一个一般的组件是由 userInterface 和 api 驱动组件外部逻辑的运行;
  • saveEffect 能够通过 lowcode 的 setter 层以 api(props)的形式动静注入,而后在 onChange 等对外的接口中抛出即可,齐全不影响组件的外部逻辑;
  • 组件抛出 value 和 saveEffect 后,零碎会主动调用咱们开发的解析插件进行数据解析和保留,从而实现组件的 ” 副作用 ” 间联动成果;

总结与瞻望

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

将来咱们打算在低代码平台中退出 逻辑编排能力 ,最终实现 逻辑代码的图形化表白,进一步反对更为简单的车间搭建。

正文完
 0