Amap low code practice

background

1. The map data operation platform has gradually transformed from a large-scale WebGIS "comprehensive operation" to a streamlined "simple operation" that combines man-machine and WYSIWYG;

1eb49ff1e8c5c19d1a3dab579f509887.png

Figure 1-1 Comprehensive operations and streamlined operations

2. The characteristic of streamlined operations is that single workshop interaction is simple, but each workshop has customized business logic (difficult to configure and implement, suitable for low-code methods with scalability);

3. In the process of low-code construction of the work platform, even any simple work workshop has logic such as data verification, component linkage, and save result conversion (the sign scene workshop in the figure below is an example);

4. The goal of low-code construction of the work platform is to allow non-R&D students such as products and processes to independently build workshops. Therefore, logical operations should be visualized as much as possible and less or no logic code should be written;

5. Non-front-end R&D students do not have a good understanding of some basic concepts of the front-end: such as event-driven, immutable data principle, two-way data binding, (non-)controlled components, etc.;

Questions and Analysis

A simple linkage example

5fba88188d491a504aec0dd98770d66e.gif

Figure 2-1 Signage scene determination workshop

Components involved : 7

Component linkage description: During initialization, the second and third job items are grayed out and disabled; when "No" is selected for the previous job item, the next job item is activated; when "Yes" is selected for the previous job item, subsequent job items are cleared;

Question:  For such a basic linkage between components, the solution for low-code engines is to bind event callback functions in WebIDE, and implement logic by writing code in the function. For front-end R&D, such a solution can be completed quickly with more than a dozen lines of code, but for non-R&D students (products, processes), etc., they need to understand event-driven, data immutability principles, etc., and it is very difficult to implement. Therefore, we need to explore a more friendly solution: the above linkage function can be realized without code or an expression.

Code analysis in examples

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


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
  }
}

  • As you can see from the pseudocode above, the implementation of a workshop is divided into: UI + logic

  • In the visual construction, the UI part and simple interactions are implemented within the component, and the cross-component logic part is implemented by event callbacks. The callback function can be split into the following four parts, main functions and related concepts :

    • Data filtering : filtering the required data from function parameters (involving event-driven concepts)

    • Two-way binding: controlled components are driven by external data, and dependent data sources need to be updated after state changes (controlled components, two-way binding, immutability principle)

    • Data linkage: update of other data, linkage communication between components; (business logic)

    • Data update: front-end framework API;

Thoughts on how to simplify the basic concepts in the examples

How to prevent non-R&D students from ignoring the basic concepts and syntax of the front-end and visually realizing component communication and linkage is the key to reducing the difficulty of visual construction. To this end, we separate the four parts of the function body (data filtering, two-way binding, business logic linkage, and data update):

  • In view of the data filtering capability in callback functions in event-driven events, we have developed data filters. Function parameters are statically declared in a tree structure in the component setter of the design page. Users only need to select the corresponding parameters to achieve similar data deconstruction and function of assignment

10cbc28de3a49e1ce92139c53e5505a5.png

Figure 2-1 Building a data filter on the page

  • In view of the two-way binding, data linkage, and immutable principles, we agreed on a concise data storage syntax and developed a specific syntax parsing plug-in for this syntax. The specific design is as follows:

    • A scenario where a component state change on the page triggers a linkage to other component state changes. We believe this is a "side effect" saveEffect of the component's state change process;

    • Each "side effect" contains three parts, namely source data, target data, and conversion logic. Take the above linkage as an example: source data A, target data B. The conversion logic is that when A is 1, B is cleared. The corresponding data structure is :

 
  
一个"副作用"对象由三部分构成


{
  // 源数据
  fromPath: 'e.target.value', 
  // 目标数据
  toPath: 'state.B',
  // 转换逻辑
  formatFunc: 'function switchStoreValue(value, state) { return A == '1' ? '' : state.B };'
}
    • We provide a saveEffect setter in the low-code component, allowing users to select the source data of "side effects", determine the target value, and write conversion logic. This part of the logic is injected into the component, and the component will output the value and the value in the callback function. The saveEffect object is thrown at the same time, and is finally parsed and executed by our syntax parsing plug-in to achieve component linkage;

  • For data updates, we believe that users do not need to pay attention to the API of the framework layer at all, so we developed the automatic binding setter @ali/lowcode-setter-a-event-setter to bind the component's callback function to the saveState global function. Automatically perform data update operations in the saveState global function. The following is an example of a linkage "side effect"

 
  
// 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
      },
      ...
    ]
  }
}

For the above saveEffect object, the user only needs to specify the target value path, and the plug-in will automatically parse the syntax of the path, generate new references for all parent structures of activeKey, and finally automatically call setState to update the component;

a9907558157a0724622ae78dbafc48b1.png

Figure 2-2 The plug-in automatically updates the parsed path to a new reference

Effect


An example of an online workshop

Use the saveEffect setter to save code before and after comparison. Taking the guide line content workshop as an example, we need to assign an attribute to a guide line direction. The UI operation is as shown below. Select the lane and update the type of the lane.

3541a47ffbfde0d5068239a059753ea8.gif

Figure 3-1 Update lane attributes

The native low-code engine needs to implement the following code in the page 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
  });
}

Using the saveEffect object combined with the syntax parsing plug-in, the user only needs to fill in one sentence in the target value (in most cases, the conversion function does not need to be modified);

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

The corresponding setter UI is as follows:

d1d3b5123ed87c5d164a03b699a04a6b.png

How to connect procode component to saveEffect

After understanding the principle of saveEffect, if you want to connect ordinary UI components to saveEffect, how to modify it? Is the modification cost high?

1584e326e8ed787fa946385670e8fa46.png

As can be seen from the picture above

  • A common component is driven by userInterface and API to run the internal logic of the component;

  • saveEffect can be dynamically injected through the setter layer of lowcode in the form of api (props), and then thrown in external interfaces such as onChange, without affecting the internal logic of the component at all;

  • After the component throws value and saveEffect, the system will automatically call the parsing plug-in we developed to parse and save the data, thereby realizing the linkage effect between the "side effects" of the component;

Summary and Outlook

This article mainly introduces how we have reduced the difficulty of linkage and data processing between components in the work platform through custom plug-ins, setters, component standardization, etc., and achieved the goal of allowing non-R&D students to independently build our small-grained workshop . In addition, we have also developed for loop components , if/else and other logical components in the visual aspect , with the intention of using visual components to implement some basic template syntax . Combined with the workshop template we developed , users only need to Completing a small amount of custom logic enables workshop development.

In the future, we plan to add logic orchestration capabilities to the low-code platform , and ultimately achieve graphical expression of logic code to further support more complex workshop construction.

Recommended related reading:

Follow "Amap Technology" to learn more

Guess you like

Origin blog.csdn.net/amap_tech/article/details/130979610