mcpField
W
widget-coherence

widget-coherence

github.com/serac-labs开发7761 次安装9 周前更新
代码仓库

关于 widget-coherence

面向 ServiceNow Service Portal 小组件开发的技能,重点是保持服务器脚本、客户端控制器与 HTML 模板之间的一致性。它帮助开发者梳理数据与操作的流转,并在部署前发现不匹配之处。

主要功能

  1. 01检查小组件三方约定
  2. 02核对服务器与客户端操作
  3. 03指导初始化数据属性
  4. 04提供 Angular 指令参考
  5. 05部署前验证清单

适用场景

  1. 01检查小组件数据绑定
  2. 02查找客户端与服务器操作不匹配
  3. 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