ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

ThingsBoard 仪表板自定义动作实战:一键复制设备 Access Token 到剪贴板

ThingsBoard 仪表板自定义动作实战:一键复制设备 Access Token 到剪贴板 物联网后端数据可视化消息队列【免费下载链接】thingsboardAll-in-one IoT Platform - Device management, data collection, processing and visualization.项目地址https://gitcode.com/GitHub_Trending/th/thingsboard点击查看免费下载在 ThingsBoard 的仪表板 Widget 中可以通过自定义动作Custom Action在用户点击时执行一段 JavaScript 逻辑从而实现设备管理操作的快速入口。本文以官方提供的custom_action_copy_access_token示例为核心讲解如何编写一个一键复制设备 Access Token 到剪贴板的动作用户点击按钮后前端通过deviceService拉取当前设备的凭证Credentials将credentialsId即 Access Token写入系统剪贴板并弹出国际化成功提示。读完本文你将掌握 ThingsBoard 自定义动作的完整编写范式$injectorservicesMap的服务获取方式、entityId守卫判断、跨浏览器剪贴板复制工具函数以及源码级的工作原理。自定义动作Custom Action简介在 ThingsBoard 中仪表板上的每一个 Widget 都可以配置一个或多个动作Action动作可以绑定到 Widget 标题按钮、单元格点击、行双击等事件源actionSource。当动作类型选择为自定义动作Custom Action时系统会将当前动作上下文暴露给一段用户编写的 JavaScript这段脚本运行在 Angular 应用内部因此可以访问到注入器$injector与各类业务服务直接操作当前选中的实体数据。动作脚本中可以使用的关键上下文变量包括变量含义widgetContext当前 Widget 的运行上下文包含$scope、servicesMap、showSuccessToast等方法$event触发动作的 DOM 事件对象$injectorAngular 依赖注入器可通过$injector.get()获取任意已注册服务entityId当前 Widget 数据源对应的实体 ID形如{id: xxx, entityType: DEVICE}entityName当前实体的名称servicesMapWidget 上下文中注册的服务名与服务的映射表用于从$injector中取服务本文示例正是使用entityId判断当前实体是否为设备DEVICE进而执行凭证获取与复制逻辑。完整示例代码复制设备 Access Token 到缓冲以下是官方提供的核心示例代码出自仓库 custom_action_copy_access_token.md可在 Widget 动作编辑器的示例中选择加载var $injector widgetContext.$scope.$injector; var deviceService $injector.get(widgetContext.servicesMap.get(deviceService)); var $translate $injector.get(widgetContext.servicesMap.get(translate)); var $scope widgetContext.$scope; if (entityId.id entityId.entityType DEVICE) { deviceService.getDeviceCredentials(entityId.id, true).subscribe( (deviceCredentials) { var credentialsId deviceCredentials.credentialsId; if (copyToClipboard(credentialsId)) { $scope.showSuccessToast($translate.instant(device.accessTokenCopiedMessage), 750, top, left); } } ); } function copyToClipboard(text) { if (window.clipboardData window.clipboardData.setData) { return window.clipboardData.setData(Text, text); } else if (document.queryCommandSupported document.queryCommandSupported(copy)) { var textarea document.createElement(textarea); textarea.textContent text; textarea.style.position fixed; document.body.appendChild(textarea); textarea.select(); try { return document.execCommand(copy); } catch (ex) { console.warn(Copy to clipboard failed., ex); return false; } document.body.removeChild(textarea); } }这段代码的运行流程可以概括为通过widgetContext.$scope.$injector获取 Angular 注入器用注入器按servicesMap中的键名取出deviceService与translate两个服务校验entityId存在且entityType DEVICE确保动作只对设备实体生效调用deviceService.getDeviceCredentials(entityId.id, true)拉取设备凭证订阅成功后取出credentialsId即 Access Token调用本地copyToClipboard()写入剪贴板复制成功后通过$scope.showSuccessToast()展示国际化成功提示。逐段解析从注入器到服务获取获取 Angular 注入器与业务服务var $injector widgetContext.$scope.$injector; var deviceService $injector.get(widgetContext.servicesMap.get(deviceService)); var $translate $injector.get(widgetContext.servicesMap.get(translate)); var $scope widgetContext.$scope;自定义动作脚本运行在 Widget 组件的上下文内widgetContext.$scope指向当前组件的作用域其上挂有 Angular 的$injector。因此可以通过$injector.get()获取任意已注入的服务实例而不需要在脚本中手动构造。widgetContext.servicesMap是 Widget 上下文暴露的服务注册表。从源码 widget.component.ts 可以看到widgetContext.servicesMap ServicesMap其中注册了deviceService、translate、entityService、assetService、attributeService、dialogs、customDialog等服务。使用servicesMap.get(deviceService)而不是直接写字符串常量是为了保持脚本与服务键名的解耦即使键名变化脚本也能通过映射动态取到正确服务。官方在 custom-sample-js.raw 中给出了类似的服务获取范式例如//let $injector widgetContext.$scope.$injector; //let deviceService $injector.get(widgetContext.servicesMap.get(deviceService));这说明该写法是 ThingsBoard 自定义动作的标准实践被广泛用于删除实体、编辑实体、地图打点等各类动作脚本中。实体类型守卫if (entityId.id entityId.entityType DEVICE) {entityId由 Widget 的数据源绑定实体提供包含id与entityType两个字段。加上这层判断可以避免在动作作用于非设备实体如ASSET、ENTITY_GROUP时抛出错误保证脚本的健壮性。这是所有设备相关自定义动作都应该保留的前置校验。getDeviceCredentials 的底层实现同步与异步两种模式示例中调用的是deviceService.getDeviceCredentials(entityId.id, true)第二个参数true表示同步sync模式。从源码 device.service.ts 可以看出该方法的完整定义public getDeviceCredentials(deviceId: string, sync: boolean false, config?: RequestConfig): ObservableDeviceCredentials { const url /api/device/${deviceId}/credentials; if (sync) { const responseSubject new ReplaySubjectDeviceCredentials(); const request new XMLHttpRequest(); request.open(GET, url, false); request.setRequestHeader(Accept, application/json, text/plain, */*); const jwtToken AuthService.getJwtToken(); if (jwtToken) { request.setRequestHeader(X-Authorization, Bearer jwtToken); } request.send(null); if (request.status 200) { const credentials JSON.parse(request.responseText) as DeviceCredentials; responseSubject.next(credentials); } else { responseSubject.error(null); } return responseSubject.asObservable(); } else { return this.http.getDeviceCredentials(url, defaultHttpOptionsFromConfig(config)); } }关键点说明请求端点GET /api/device/{deviceId}/credentials即向后端服务请求指定设备的凭证信息同步模式synctrue使用浏览器原生XMLHttpRequest同步请求open(GET, url, false)并手动附加X-Authorization: Bearer JWT请求头完成身份认证返回的DeviceCredentials通过ReplaySubject包装成Observable返回异步模式syncfalse默认使用 AngularHttpClient发起请求携带默认 HTTP 选项可通过config参数控制错误处理等行为。由于示例动作运行在 Widget 的点击事件处理流程中使用同步模式可以更直接地在订阅回调里拿到结果。返回值类型DeviceCredentials中的关键字段即为credentialsId——对于ACCESS_TOKEN类型的设备凭证它就是设备的 Access Token 本身。后端对应的凭证管理接口也可在仓库中找到对应实现设备凭证的保存由saveDeviceCredentials通过POST /api/device/credentials完成这里不再展开。跨浏览器剪贴板复制copyToClipboard 工具函数function copyToClipboard(text) { if (window.clipboardData window.clipboardData.setData) { return window.clipboardData.setData(Text, text); } else if (document.queryCommandSupported document.queryCommandSupported(copy)) { var textarea document.createElement(textarea); textarea.textContent text; textarea.style.position fixed; document.body.appendChild(textarea); textarea.select(); try { return document.execCommand(copy); } catch (ex) { console.warn(Copy to clipboard failed., ex); return false; } document.body.removeChild(textarea); } }该函数实现了两级浏览器兼容策略IE 系方案优先使用window.clipboardData.setData(Text, text)这是旧版 IE 专有的剪贴板写入方式现代浏览器方案当document.queryCommandSupported(copy)可用时动态创建一个隐藏位置的textarea将文本写入其textContent选中后调用document.execCommand(copy)完成复制并在结束时移除该临时元素异常兜底复制过程包在try/catch中失败时向控制台输出console.warn(Copy to clipboard failed., ex)并返回false供上层判断是否提示成功。需要注意document.execCommand(copy)在较新的浏览器中已被标记为废弃deprecated但在仪表板这类需要兼容多种浏览器环境的场景下该方案依然是覆盖最广的稳妥选择。如果部署环境仅限较新的 Chromium 内核也可以考虑改用异步的navigator.clipboard.writeText()API 并配合catch处理剪贴板权限拒绝的情况。成功提示Toast 与国际化复制成功后示例通过如下代码向用户反馈结果$scope.showSuccessToast($translate.instant(device.accessTokenCopiedMessage), 750, top, left);其中$translate.instant(device.accessTokenCopiedMessage)调用 Angular 国际化翻译服务的instant()方法根据当前界面语言即时取出对应文案。该键在英文语言包 locale.constant-en_US.json 中定义为Device access token has been copied to clipboard同时在中文、阿拉伯文、加泰罗尼亚文、捷克文、丹麦文等 28 种语言包locale 目录中都有对应翻译因此提示信息会随界面语言自动切换showSuccessToast(message, duration, verticalPosition, horizontalPosition)是 Widget 作用域提供的成功提示方法。从源码 dynamic-widget.component.ts 可以看到其签名showSuccessToast(message: string, duration: number 1000, verticalPosition bottom, horizontalPosition left, target?: string)内部转发给this.ctx.showSuccessToast(...)完成实际渲染示例中传入750表示提示持续 750mstop、left 指定提示出现在屏幕左上角区域。如果希望提示停留更久或改变位置可以自行调整参数例如$scope.showSuccessToast(message, 3000, bottom, center)。在 Widget 中配置该动作要将这段代码应用到实际仪表板操作步骤如下进入仪表板编辑模式选中目标设备列表 Widget如设备表、设备卡片打开该 Widget 的动作Actions配置在actionSource如单元格点击、按钮下新增动作将动作类型选择为自定义动作并把上述完整代码粘贴到脚本编辑器中保存配置并退出编辑模式点击对应设备即可验证页面右上角按提示位置参数弹出Device access token has been copied to clipboard随后可将 Access Token 粘贴到任意位置使用。在编写动作脚本时还可以参考仓库中其他官方示例来熟悉动作脚本的通用写法例如 custom_action_delete_device_confirm.md带确认对话框的删除动作、custom_action_display_alert.md弹窗提醒动作等它们共享同一套$injector/servicesMap/entityId上下文模型。小结本文围绕 ThingsBoard 官方示例custom_action_copy_access_token展开了完整的实战讲解从自定义动作的上下文模型widgetContext、$injector、servicesMap、entityId到deviceService.getDeviceCredentials()的同步/异步双模式源码实现再到跨浏览器剪贴板复制函数与国际化成功提示。通过这个示例你可以举一反三在仪表板中实现复制设备密钥/证书、复制实体 ID、快速跳转等各类基于前端服务的自定义动作把常用运维操作以一次点击的方式沉淀到看板中提升日常设备管理效率。相关参考文件官方示例文档custom_action_copy_access_token.md设备服务实现device.service.tsWidget 上下文服务注册widget.component.tsToast 提示实现dynamic-widget.component.ts英文文案定义locale.constant-en_US.json官方动作脚本范式custom-sample-js.raw赞分享物联网后端数据可视化消息队列【免费下载链接】thingsboardAll-in-one IoT Platform - Device management, data collection, processing and visualization.项目地址https://gitcode.com/GitHub_Trending/th/thingsboard点击查看免费下载相关推荐ThingsBoard 实体组自定义动作实战用 JavaScript 将 Entity Id 复制到剪贴板ThingsBoard 实体组自定义动作实战用 JavaScript 将 Entity Id 复制到剪贴板 本篇指南围绕 ThingsBoard 前端ui物联网后端数据可视化消息队列ThingsBoard 自定义操作实战编写复制设备 Access Token 的实体组表格操作ThingsBoard 自定义操作实战编写复制设备 Access Token 的实体组表格操作 在 ThingsBoard 的实体组Entity Group物联网后端数据可视化消息队列ThingsBoard 仪表板自定义动作实战用 customDialog 与 HTML 模板实现设备/资产创建对话框ThingsBoard 仪表板自定义动作实战用 customDialog 与 HTML 模板实现设备/资产创建对话框 本指南聚焦 ThingsBoard 仪表物联网后端数据可视化消息队列创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表