导语

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

优维低代码实践连载第⑤期

《编排优化Plus》

在上一章节中,我们编排完成了任务列表的查询,以及新增任务实例这两功能,在本章节中,我们将对其进行功能的完善,包括:任务修改,任务删除,点击任务跳转至任务详情页面,搜索查询能力完善等,那么下面让我们开始学习吧!

一、任务修改

在上一章节的最后一点我们完成了任务实例的新增,接下来我们要用对任务进行修改,需要我们在编排开辟新的入口(Tabel增加操作列),并调用相关的Proivder接口进行修改,下面跟着我的编排快速过下吧~

Table属性参数修改

属性面板-属性:# ...  columns:    - dataIndex: name      key: name      title: 任务名称    - dataIndex: state      key: state      title: 状态    - dataIndex: assignee      key: assignee      title: 负责人    # 新增项    - dataIndex: operator      title: 操作      key: operator      # useChildren&useBrick用法,后续章节会展开讲解      useChildren: '[operator]'# ...


Table下新增构件并进行属性修改


将鼠标移入构件树上的Table构件,右侧将出现+图标, 点击图标添加构件, 将出现新增构件弹窗,参数如下:


# 父节点默认不可修改父节点: Table# 挂载点等于useChildren的值,useChildren的值需要大括号包裹挂载点: [operator]# 选择构件构件: basic-bricks.general-button示例(选择可快速创建构件): 随便选择一个


新增完构件后,我们需要对这个构件进行属性编辑

数据名称: isEdit类型: ValueValue: false

然后对我们刚刚新增的构件进行属性编辑

属性面板-属性:  buttonIcon:    lib: easyops    category: default    icon: edit    color: blue  buttonType: text  # 构件样式,设置为行内元素  style:    display: inline-block事件面板-生命周期:  general.button.click:    # 将 CTX.isEdit 设置为true,涉及数据逻辑联动,下面会有说明    - action: context.replace      args:        - isEdit        - true    # 设置表单的静态值    - target: '#AddTaskForm'      properties:        staticValues:          # 说明一下表达式含义:设置实例ID字段等于行数组的实例ID          # DATA为特殊表达式,尽在useChildren或useBrick下面进行使用          # 可以获取其父元素传递的值          # 这里 DATA = {           #   rowData: { instanceId: 'xxx', name: 'xxx', ... },          #   ...          # }          # 因此可以使用以下表达式获取该行的实例ID          instanceId: <% DATA.rowData.instanceId %>    - target: '#AddTaskForm'      method: setInitValue      args:        # 设置表单初始值        - <% DATA.rowData %>      # 打开弹窗    - target: '#modalAddTask'      method: open


弹窗&添加按钮修改

属性面板-属性:  id: modalAddTask  # 修改此行数据  # "track context" 为特殊表达式,用以监听用户自定义变量的值  # 若监听的值发生更新,则会更新后续表达式中的内容  # 从而引起构件的变化  # 下方为三元表达式语法,含义为:  # 当 CTX.isEdit 等于 true 时,弹窗名称为:编辑任务  # 当 CTX.isEdit 等于 false 时, 弹窗名称为:添加任务  modalTitle: '<% "track context", CTX.isEdit ? "编辑任务" : "添加任务" %>'  closeWhenOk: false  maskClosable: false
事件面板-事件:general.button.click:  # 新增项  - action: context.replace    args:      - isEdit      - false  # ...


Form表单修改


事件面板-事件:  validate.error:    - action: message.error      args:        - 表单填写失败  validate.success:    - target: '#modalAddTask'      properties:        okDisabled: true    # 新增if逻辑,这里表示,如果 CTX.isEdit是false的话,则代表是新建状态    # 调用创建实例接口    - if: <% !CTX.isEdit %>      useProvider: providers-of-cmdb.instance-api-create-instance      # 上个章节的内容,这里不做展开      # ...    # ======== 分割线 ==============    # 新增if逻辑,这里表示,如果 CTX.isEdit是true的话,则代表是编辑状态    # 调用编辑实例接口    - if: <% CTX.isEdit %>      useProvider: providers-of-cmdb.instance-api-update-instance      args:        - TASK_FOR_VB_LESSON        - <% EVENT.detail.instanceId %>        - |-          # 这里是入参,获取表单暴露的数据中指定的字段          # _.pick 是第三方工具库 lodash 提供的处理数据的函数          # 在表达式中可以直接使用,用以处理数据          <%            _.pick(EVENT.detail, [              "name",              "state",              "assignee",              "reporter",              "time",              "description",            ])          %>      callback:        success:          # 回调方法,同新增逻辑一致          - action: message.success            args:              - 任务修改成功          - target: '#modalAddTask'            properties:              okDisabled: false          - action: context.refresh            args:              - taskList          - target: '#modalAddTask'            method: close        error:          - action: handleHttpError


二、任务删除

为Table新增删除按钮


在做完修改功能后,增删改查我们就剩最后一个删除功能了,我们就已最简单的实现结束这块功能吧~


我们要在刚刚Table操作列新增的编辑按钮后面加上一个删除按钮;在构件树上找到 Table 下挂在点为: [operator], 然后在它下面新增构件, 弹窗参数如下:


# 父节点默认不可修改父节点: Table# 挂载点等于useChildren的值,useChildren的值需要大括号包裹挂载点: [operator]# 选择构件构件: basic-bricks.general-button示例(选择可快速创建构件): 随便选择一个


删除按钮入参修改


属性面板-属性:  buttonIcon:    lib: easyops    category: default    icon: delete    color: red  buttonType: text  style:    display: inline-block事件面板-事件:  general.button.click:    # 这里简单实现,点击删除按钮,直接调用删除接口,进行删除    # 然后触发 taskList 重新请求数据,完成渲染    - useProvider: providers-of-cmdb.instance-api-delete-instance      args:        - TASK_FOR_VB_LESSON        - <% DATA.rowData.instanceId %>      callback:        success:          - action: message.success            args:              - 任务删除成功          - action: context.refresh            args:              - taskList        error:          action: handleHttpError


三、任务详情页面跳转

URL动态参数详解


在完成了增删改查之后,我们要对我们的功能进一步完善,现在我们需要一个任务详情页面,入口是从任务列表页面进行跳转,那么我们要怎么做呢?首先我们要思考一个问题,一个详情页面,我们要怎么知道当前页面是哪一条实例的详情呢?


最常用的方式就是在 URL 上面携带信息,然后详情页面从 URL 中获取信息,然后进行接口请求,获取信息后再渲染页面上,编排也是如此;在之前的章节中,我们已经介绍了一种方式,通过 QUERY 表达式,可以获取 URL 上面的参数,现在我们介绍另外一种可以从 URL 上面动态参数的表达式 PATH,他们的使用示例如下:


QUERY表达式获取参数:  # 路由 page1 参数设置  path: '${APP.homepage}/page1'  # 实际渲染时,用户根据自己需求,添加动态参数 { a:1, b:2, c: helloWorld }  # URL将识别成以下格式  URL: 'https://admin.easyops.local/next/page1?a=1&b=2&c=helloWorld'  # 则 QUERY.a = 1, QUERY.b = 2, QUERY.c = helloWorld # =========== 分割线 ===========PATH表达式获取参数:  # 路由 page2 参数设置  # 请注意 path 上面的 :a, :b, :c, 这几个就是我们认为的动态路由参数  path: '${APP.homepage}/page2/:a/task/:b/detail/:c/edit'  # 实际渲染时,用户根据自己需求,添加动态参数 { a:1, b:2, c: helloWorld }  # URL将识别成以下格式  URL: 'https://admin.easyops.local/next/page2/1/task/2/detail/helloWorld/edit'  # 则 PATH.a = 1, PATH.b = 2, PATH.c = helloWorld


新增路由页面(任务详情)


在介绍完这两个表达式之后,我们将使用 PATH 的方式,创建新的路由页面,并完成任务详情跳转这个功能,下面进入编排步骤:


别名: 任务详情path: "${APP.homepage}/task/:instanceId/detail"选择主题: UI8.0主题下的详情页


DATA面板添加数据


在新增完路由后,打开在左侧 DATA 面板,添加数据 taskDetail,入参如下:


数据名称: taskDetail类型: ProviderProvider(接口): providers-of-cmdb.instance-api-get-detailArgs(参数):  - TASK_FOR_VB_LESSON  # 这里路径上面已经配置了 :instanceId, 所以我们可以根据通过 PATH 表达式获取到具体的值  - <% PATH.instanceId %>


构件属性修改


然后从构件树上找到 brick-descriptions 构件,将其属性修改如下:


属性面板-属性:  column: 4  dataSource: <% CTX.taskDetail %>  itemList:    - label: 任务名称      field: name    - label: 任务描述      field: description    - label: 状态      useChildren: '[tag]'    - label: 工时      field: time    - label: 负责人      field: assignee    - label: 汇报人      field: reporter


任务列表页面编排修改


在做完这一切之后,我们回到任务列表的编排页面中,进行页面编排修改,首先定位到 Table 构件,将其属性入参修改为如下:


columns:  - dataIndex: name    key: name    title: 任务名称    # 新增项    useChildren: '[name]'  # 其他不做修改,只需要增加这一行属性即可  # ...


然后在 TABLE 的节点下新增 Link 构件


# 父节点默认不可修改父节点: Table# 挂载点等于useChildren的值,useChildren的值需要大括号包裹挂载点: [name]# 选择构件构件: presentational-bricks.brick-link示例(选择可快速创建构件): 随便选择一个


并将新增 Link 构件的属性修改为:


属性面板-属性:  label: <% DATA.rowData.name %>  # url由动态参数由列表行数据提供  url: '<% `${APP.homepage}/task/${DATA.rowData.instanceId}/detail` %>'  hideExternalIcon: true


四、为Table增加查询条件

之前我们做的查询其实只是批量地将数据查询回来并进行展示,相对来说还比较粗糙,现在我们需要将查询细致化,增加多一些查询条件,方便能够精准定位到我们需要的数据,那么接下来也开始关于这块的编排吧!


相信大家看到左侧DATA面板一直有两个参数filters跟query,但是我们之前的章节一直没有提及;本节课将利用这两个参数,结合taskList,进行数据查询,那么我们要怎么做呢?跟着我一起修改编排吧


DATA属性修改


数据名: filters类型: ValueArgs(参数):  assignee: <% QUERY.assignee %>  name: <% QUERY.name %>
数据名: query类型: ValueArgs(参数):  |-    <%      {        $and: [          {            ...(CTX.filters.name              ? {                  name: {                    $like: `%${CTX.filters.name}%`,                  },                }              : {}),            ...(CTX.filters.assignee              ? {                  assignee: {                    $eq: `${CTX.filters.assignee}`,                  },                }              : {}),          },        ],      }    %>


数据名称: taskList类型: ProviderProvider(接口): providers-of-cmdb.instance-api-post-search-v3Args(参数):  - TASK_FOR_VB_LESSON  - fields:      - name      - state      - assignee      - reporter      - description    page: '${QUERY.page=1|number}'    pageSize: '${QUERY.pageSize=20|number}'    # 新增项    query: <% CTX.query %>Extra provider settings(额外的接口配置):  lazy: trueExtra basic settings(额外的基础配置):  track: true


构件属性修改


找到 Table 上放的两个构件,Input & Select, 分别对他们进行修改,如下


属性面板-属性:  placeholder: 输入任务名称  q: <% CTX.filters.name %>  shouldUpdateUrlParams: false事件面板-事件:  filter.update:    # history.pushQuery 为系统提供的方法,用以更新 URL 上的动态参数    # 若原先 url: http://admin.easyop.local/next/page1?name=1    # 执行完下面事件后,url将变为:     # http://admin.easyops.local/next/page1?name=xxx&page=1    - action: history.pushQuery      args:        - name: <% EVENT.detail.query %>          page: 1        # history.pushQuery 第二个入参,notify默认为true        # 设置成false代表更新完URL后不触发页面更新        - notify: false    # context的语法之一,表示更新 CTX.filters 中的 name    - action: context.assign      args:        - filters        - name: <% EVENT.detail.query %>


属性面板-属性:  placeholder: 筛选负责人  objectId: USER  inputBoxStyle:    width: 200px  instanceQuery:    state: valid  fields:    label:      - name    value: name  labelTemplate: '#{name}'  value: <% CTX.filters.assignee %>  allowClear: true事件面板-事件:  forms.cmdb-instance-select.change:    # 逻辑同上,不做展开    - action: history.pushQuery      args:        - assignee: '${EVENT.detail}'          page: 1        - notify: false    - action: context.assign      args:        - filters        - assignee: '${EVENT.detail}'


做完这一切编排修改后,我们的查询功能也就丰富完善啦!


五、结语

通过本章节,您已学会查询,编辑,删除,路由页面跳转等高级操作啦,这已经能够满足日常编排工作的大部分场景啦!