优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维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
类型: Value
Value: 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
类型: Provider
Provider(接口): providers-of-cmdb.instance-api-get-detail
Args(参数):
- 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
类型: Value
Args(参数):
assignee: <% QUERY.assignee %>
name: <% QUERY.name %>
数据名: query
类型: Value
Args(参数):
|-
<%
{
$and: [
{
...(CTX.filters.name
? {
name: {
$like: `%${CTX.filters.name}%`,
},
}
: {}),
...(CTX.filters.assignee
? {
assignee: {
$eq: `${CTX.filters.assignee}`,
},
}
: {}),
},
],
}
%>
数据名称: taskList
类型: Provider
Provider(接口): providers-of-cmdb.instance-api-post-search-v3
Args(参数):
- 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: true
Extra 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}'
做完这一切编排修改后,我们的查询功能也就丰富完善啦!
五、结语
通过本章节,您已学会查询,编辑,删除,路由页面跳转等高级操作啦,这已经能够满足日常编排工作的大部分场景啦!