关于 widget-coherence
面向 ServiceNow Service Portal 小组件开发的技能,重点是保持服务器脚本、客户端控制器与 HTML 模板之间的一致性。它帮助开发者梳理数据与操作的流转,并在部署前发现不匹配之处。
主要功能
- 01检查小组件三方约定
- 02核对服务器与客户端操作
- 03指导初始化数据属性
- 04提供 Angular 指令参考
- 05部署前验证清单
适用场景
- 01检查小组件数据绑定
- 02查找客户端与服务器操作不匹配
- 03核对点击处理器与控制器方法
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ serac-labs/ serac --skill widget-coherence安装后在 Claude Code 中输入/widget-coherence确认已加载。
详细介绍
ServiceNow Service Portal 的组件通信一致性
Service Portal 的组件必须确保服务器脚本、客户端控制器和 HTML 模板之间能够完美通信。这一点不容忽视——这些组件通信不正确时,组件就会失效。
三方契约
每个组件都需要同步通信:
1. 服务器脚本必须:
- 初始化 HTML 将引用的所有
data.*属性 - 处理客户端通过
c.server.get()发送的每个input.action - 按客户端所需的格式返回数据
2. 客户端控制器必须:
- 实现 HTML 中
ng-click调用的每个方法 - 使用
c.server.get({action: 'name'})与服务器通信 - 在服务器响应后更新
c.data
3. HTML 模板必须:
- 只引用服务器提供的
data.*属性 - 只调用客户端控制器中定义的方法
- 使用正确的 Angular 指令和绑定
数据流模式
服务器 → 客户端 → HTML
// SERVER SCRIPT
;(function () {
data.incidents = []
data.loading = true
var gr = new GlideRecord("incident")
gr.addQuery("active", true)
gr.setLimit(10)
gr.query()
while (gr.next()) {
data.incidents.push({
sys_id: gr.getUniqueValue(),
number: gr.getValue("number"),
short_description: gr.getValue("short_description"),
})
}
data.loading = false
})()
// CLIENT CONTROLLER
api.controller = function ($scope) {
var c = this
c.selectIncident = function (incident) {
c.selectedIncident = incident
}
}
<div ng-if="data.loading">Loading...</div>
<div ng-if="!data.loading">
<div ng-repeat="incident in data.incidents" ng-click="c.selectIncident(incident)">
{{incident.number}}: {{incident.short_description}}
</div>
</div>
客户端 → 服务器(操作)
// CLIENT CONTROLLER
c.saveIncident = function () {
c.server
.get({
action: "save_incident",
incident_data: c.formData,
})
.then(function (response) {
if (response.data.success) {
c.data.message = "Saved successfully"
}
})
}
// SERVER SCRIPT
if (input && input.action === "save_incident") {
var gr = new GlideRecord("incident")
gr.initialize()
gr.setValue("short_description", input.incident_data.short_description)
data.new_sys_id = gr.insert()
data.success = !!data.new_sys_id
}
验证清单
部署组件前,请确认:
- 服务器中的每个
data.property都在 HTML 或客户端中使用 - 每个
ng-click="c.method()"都有对应的客户端c.method - 每个
c.server.get({action: 'x'})都有对应的服务器端if(input.action === 'x') - 没有未使用的方法或未使用的数据属性
- 所有
data.*属性都在服务器端初始化(即使为空)
常见故障
操作名称不匹配
// CLIENT - sends 'saveIncident'
c.server.get({ action: "saveIncident" })
// SERVER - expects 'save_incident' (MISMATCH!)
if (input.action === "save_incident") {
}
方法名称不匹配
<button ng-click="c.saveData()">Save</button>
// CLIENT - defines save() (MISMATCH!)
c.save = function () {}
数据属性未定义
<span>{{data.user.email}}</span>
// SERVER - only sets user.name (user.email is undefined!)
data.user = { name: userName }
Angular 指令参考
| 指令 | 用途 |
|---|---|
ng-if | 有条件地渲染元素 |
ng-show/ng-hide | 切换可见性(元素仍保留在 DOM 中) |
ng-repeat | 遍历数组 |
ng-click | 处理点击事件 |
ng-model | 双向数据绑定 |
ng-class | 动态 CSS 类 |
ng-disabled | 禁用表单元素 |
评论
支持 Markdown