前言
看完本文后你将了解如下内容:
小部件编辑器中的Settings schema的来源,用法。
编辑器的JavaScript中如何获取Settings schema设置的内容。
源码方式添加的组件,如何获取Settings schema设置的内容。源码方式添加的组件,如何显示在部件库中,或者说如何才能使用。这个在另一篇文章介绍。
介绍
小部件编辑器是一个用于开发自定义小部件的迷你IDE。它由顶部工具栏和四个主要部分组成:
这篇文章来介绍Settings schema
(设置模式)的作用和用法。
还记得自己第一次打开小部件编辑器的时候,左边俩栏还大概知道是什么,对于右上方这个框框,一脸问号?这是什么东西!现在看来很简单。看完文章,相信你也轻松拿下!
官网哪里有介绍?
https://thingsboard.io/docs/user-guide/contribution/widgets-development/#settings-schema-section
里面基本讲解还是如何利用TB的小部件编辑器来开发小部件。这篇文章会涉及前端源码和settings schema
之间的操作。
官网介绍中值得一提的是:他介绍了settings schema
的来源react-schema-form
和 构建测试的页面。
react-schema-form?
Github开源官方介绍
React表单是基于json模式的,用于生成和验证表单。这是angular模式表单项目,它使用material-ui来实现底层组件。
简单来说:这是一个前端工具,你传给它俩个JSON,它给你生成表单!
正好TB的前端也是angular项目,ui采用的也是material-ui。
Settings schema?
中文翻译为设置模式
。Settings schema
的JSON结构如下,分为俩部分:
schema
决定表单类型,输入框?单选框?下拉列表?日期?等等..form
决定对应表单顺序,样式等
{
"schema":{
"type":"object",
"title":"EntitiesTableSettings",
"properties":Object{...},
"required":[
]
},
"form":Array[15]
}
Settings schema
构建的表单就对应小部件编辑状态下的编辑详情页的第三个tab「高级」里面的所有表单内容。
打开react-schema-form builder先体验一把。这里表单种类很多.
打开TB的 部件包 > Entity admin widgets > Device admin table
将这个组件的设置模式中的schema对应的JOSN对象拷贝到react-schema-form builder的Schema框中,再将这个组件的设置模式中的form对应的JOSN数组拷贝到react-schema-form builder的form框中。
看看右边的表单是不是和Device admin table组件的设置>高级 中的表单内容一致呢。
可以尝试改变一下form 数组中的元素顺序,再看看表单中的元素位置会不会做相应调换呢?
所以,无论是代码级别的新建组件,还是用小部件编辑器来新建组件,都离不开使用react-schema-form构建表单!因为无论什么组件,肯得是要做一些设置的。组件编辑页的前俩个和最后一个Tab「数据」「设置」「动作」是所有组件都一样的通用设置,第三个Tab「高级」就是每个组件都不同的个性化设置!
练习
假设我们要结合TB自带的实体列表组件,实现一个设备的批量RPC组件,如下图。
实现思路
- 实体列表的表格添加复选框,用来多选要控制的设备。
复选框,input和按钮我是通过改源码实现,本文不讲解,只介绍settings schema相关内容。
- 高级设置中,新增表单,供填写要控制的多个方法名method。
- 表格初始化时,获取方法名method,生成对应个数的input框,供输入params参数。
- 表格最后添加一个按钮,点击按钮后,获取对应method和params,
- 调用angular项目中的服务DeviceService中的sendOneWayRpcCommand或者sendTwoWayRpcCommand方法来循环发送多个设备的多个RPC命令。
表单构建
打开react-schema-form builder对应输入下面内容:
Form
[
"enableBatchRpc",
{
"key": "batchRpc",
"add": "添加",
"style": {
"add": "btn-success"
},
"items": [
"batchRpc[]"
]
}
]
schema
{
"type": "object",
"title": "Test",
"properties": {
"enableBatchRpc":{
"type":"boolean",
"title":"允许批量控制设备",
"default":false
},
"batchRpc": {
"type": "array",
"title": "添加要批量控制的method",
"maxItems": 5,
"items": {
"type": "string",
"title": "method",
"required": [
"method"
]
}
}
}
}
实现表单如下:
现在我们打开TB的 部件包 > Entity admin widgets > Device admin table点击编辑。
将刚刚验证成功的schema和form,都加到Settings schema中对应的schema和form的下面。
因为Settings schema中之前就有内容,所以只需拷贝schema的properties里的内容和form 中括号[]的内容。
拷贝后的内容也列出来吧。
{
"schema": {
"type": "object",
"title": "EntitiesTableSettings",
"properties": {
"entitiesTitle": {
"title": "Entities table title",
"type": "string",
"default": ""
},
"enableSearch": {
"title": "Enable entities search",
"type": "boolean",
"default": true
},
"enableSelectColumnDisplay": {
"title": "Enable select columns to display",
"type": "boolean",
"default": true
},
"enableStickyHeader": {
"title": "Always display header",
"type": "boolean",
"default": true
},
"enableStickyAction": {
"title": "Always display actions column",
"type": "boolean",
"default": true
},
"displayEntityName": {
"title": "Display entity name column",
"type": "boolean",
"default": true
},
"entityNameColumnTitle": {
"title": "Entity name column title",
"type": "string",
"default": ""
},
"displayEntityLabel": {
"title": "Display entity label column",
"type": "boolean",
"default": false
},
"entityLabelColumnTitle": {
"title": "Entity label column title",
"type": "string",
"default": ""
},
"displayEntityType": {
"title": "Display entity type column",
"type": "boolean",
"default": true
},
"displayPagination": {
"title": "Display pagination",
"type": "boolean",
"default": true
},
"defaultPageSize": {
"title": "Default page size",
"type": "number",
"default": 10
},
"defaultSortOrder": {
"title": "Default sort order",
"type": "string",
"default": "entityName"
},
"useRowStyleFunction": {
"title": "Use row style function",
"type": "boolean",
"default": false
},
"rowStyleFunction": {
"title": "Row style function: f(entity, ctx)",
"type": "string",
"default": ""
},
"enableBatchRpc":{
"type":"boolean",
"title":"允许批量控制设备",
"default":false
},
"batchRpc": {
"type": "array",
"title": "添加要批量控制的method",
"maxItems": 5,
"items": {
"type": "string",
"title": "method",
"required": [
"method"
]
}
}
},
"required": []
},
"form": [
"entitiesTitle",
"enableSearch",
"enableSelectColumnDisplay",
"enableStickyHeader",
"enableStickyAction",
"displayEntityName",
"entityNameColumnTitle",
"displayEntityLabel",
"entityLabelColumnTitle",
"displayEntityType",
"displayPagination",
"defaultPageSize",
"defaultSortOrder",
"useRowStyleFunction",
{
"key": "rowStyleFunction",
"type": "javascript",
"condition": "model.useRowStyleFunction === true"
},
"enableBatchRpc",
{
"key": "batchRpc",
"add": "添加",
"style": {
"add": "btn-success"
},
"items": [
"batchRpc[]"
]
}
]
}
然后点击另存为,添加到一个自定义部件包中。
新建一个仪表板,选择刚刚另存为的小部件,切到高级选项卡,查看是否出现了我们新增的表单内容.
点击按钮添加俩个method
然后回到小部件编辑器 新增俩行JavaScript代码 参考基本小部件API
console.log(self.ctx.settings.enableBatchRpc);
console.log(JSON.stringify(self.ctx.settings.batchRpc));
保存后在浏览器打开F12的console控制台的情况下,打开刚刚创建的仪表盘。可以看到成功获取了表单数据。
如何发送命令呢?同样参考基本小部件API
//分别对应https://thingsboard.io/docs/user-guide/rpc/介绍的无响应和有响应的RPC命令
self.ctx.controlApi.sendOneWayCommand("setThreshold",{"value":1});
self.ctx.controlApi.sendTwoWayCommand("setThreshold",{"value":1});
RpcApi的TypeScript定义
export interface RpcApi {
sendOneWayCommand: (method: string, params?: any, timeout?: number) => Observable<any>;
sendTwoWayCommand: (method: string, params?: any, timeout?: number) => Observable<any>;
}