展示
本页面介绍可用于创建小组件展示视图的组件。 小组件展示视图是小组件的一部分,它根据其配置接收数据,并在容器中的仪表板上显示这些数据。
展示视图由以下三部分组成:
小部件操作
小部件操作类 (WidgetView) 包含用于在演示视图模式下操作小部件的方法。
大多数小部件操作使用和/或扩展默认控制器类 CControllerDashboardWidgetView。
小部件操作类应位于 actions 目录中,并在 manifest.json 文件中的 actions 参数 (actions/widget.{id}.view/class) 中指定。
actions/WidgetView.php 示例(在 Zabbix 原生 系统信息 小部件中实现)
class WidgetView extends CControllerDashboardWidgetView {
protected function doAction(): void {
$this->setResponse(new CControllerResponseData([
'name' => $this->getInput('name', $this->widget->getDefaultName()),
'system_info' => CSystemInfoHelper::getData(),
'info_type' => $this->fields_values['info_type'],
'user_type' => CWebUser::getType(),
'user' => [
'debug_mode' => $this->getDebugMode()
]
]));
}
}
小部件视图
小部件视图类 (CWidgetView) 负责构建小部件展示视图。
小部件视图类应位于 views 目录中。
如果包含小部件视图类的文件的名称与默认名称 (widget.view.php) 不同,则必须在 manifest.json 文件 actions 参数 (actions/widget.{id}.view/view) 中指定它。
views/widget.view.php 示例
<?php
/**
* 我的自定义小部件视图。
*
* @var CView $this
* @var array $data
*/
(new CWidgetView($data))
->addItem(
new CTag('h1', true, $data['name'])
)
->show();
JavaScript
JavaScript 类负责确定仪表盘小部件的行为,如更新小部件数据、调整小部件大小、显示小部件元素等。
所有 JavaScript 操作都使用和/或扩展了所有仪表盘小部件的基础 JavaScript 类 - CWidget。 CWidget 类包含一组具有默认实现的小部件行为方法。 根据小部件的复杂性,这些方法可以直接使用或进行扩展。
CWidget 类包含以下方法:
- 定义小部件生命周期的方法:onInitialize()、onStart()、onActivate()、onDeactivate()、onDestroy()、onEdit()。
- 处理更新和显示小部件数据的方法:promiseUpdate()、getUpdateRequestData()、processUpdateResponse(response)、processUpdateErrorResponse(error)、setContents(response)。
- 修改小部件外观的方法:onResize()、hasPadding()。
JavaScript 类应位于 assets/js 目录中,并在 manifest.json 文件的 assets (assets/js) 参数中指定。
生命周期方法
小部件生命周期方法由仪表板调用,并在小部件存在于仪表板期间的生命周期的不同阶段调用。
onInitialize() 方法定义了仪表盘的初始状态和/或值,但不执行任何HTML或数据操作。 此方法在创建仪表盘(实例化仪表盘对象)时被调用,通常是通过将仪表盘添加到仪表盘页面或加载仪表盘页面来完成的。
示例:
onInitialize() {
this._time_offset = 0;
this._interval_id = null;
this._clock_type = CWidgetClock.TYPE_ANALOG;
this._time_zone = null;
this._show_seconds = true;
this._time_format = 0;
this._tzone_format = 0;
this._show = [];
this._has_contents = false;
this._is_enabled = true;
}
onStart() 方法定义了仪表盘的HTML结构,但不执行任何数据操作。 此方法在仪表盘页面首次激活之前被调用,即在仪表盘及其仪表盘完全显示给用户之前。
示例:
onStart() {
this._events.resize = () => {
const padding = 25;
const header_height = this._view_mode === ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER
? 0
: this._header.offsetHeight;
this._target.style.setProperty(
'--content-height',
`${this._cell_height * this._pos.height - padding * 2 - header_height}px`
);
}
}
onActivate() 方法通过启用自定义事件侦听器(用于响应用户操作)和启动小部件更新周期(用于保持其内容最新)使小部件处于活动状态并具有交互性。 当仪表板页面被激活时,即当其完全显示在用户界面中时,将调用此方法。
请注意,在调用 onActivate() 方法之前,小部件处于非活动状态(WIDGET_STATE_INACTIVE)。
成功调用后,小部件将转换为活动状态(WIDGET_STATE_ACTIVE)。
在活动状态下,小部件具有响应性,可侦听事件,定期更新其内容,并可与其他小部件交互。
示例:
onActivate() {
this._startClock();
this._resize_observer = new ResizeObserver(this._events.resize);
this._resize_observer.observe(this._target);
}
onDeactivate() 方法通过停用自定义事件侦听器并停止小部件更新周期来停止小部件的任何活动和交互。 当仪表板页面停用(即切换或删除)或小部件从仪表板页面中删除时,将调用此方法。
请注意,在调用 onDeactivate() 方法之前,小部件处于活动状态(WIDGET_STATE_ACTIVE)。
成功调用后,小部件将转换为非活动状态(WIDGET_STATE_INACTIVE)。
示例:
onDeactivate() {
this._stopClock();
this._resize_observer.disconnect();
}
onDestroy() 方法会在从仪表板中删除小组件之前执行清理任务,其中可能包括关闭在小组件初始化期间建立的数据库连接、清理临时数据以释放系统内存并避免资源泄漏、注销与调整大小事件或按钮点击相关的事件监听器以防止不必要的事件处理和内存泄漏等。
当删除小组件或包含该小组件的仪表板页面时,将调用此方法。
请注意,在调用 onDestroy() 方法之前,处于活动状态(WIDGET_STATE_ACTIVE)的小组件始终会通过调用 onDeactivate() 方法停用。
示例:
onDestroy() {
if (this._filter_widget) {
this._filter_widget.off(CWidgetMap.WIDGET_NAVTREE_EVENT_MARK, this._events.mark);
this._filter_widget.off(CWidgetMap.WIDGET_NAVTREE_EVENT_SELECT, this._events.select);
}
}
onEdit() 方法定义了仪表板切换到编辑模式时小部件的外观和行为。
当仪表板切换到编辑模式时会调用此方法,通常是在用户与小部件的 Edit 按钮或仪表板的 Edit dashboard 按钮交互时。
示例:
onEdit() {
this._deactivateGraph();
}
更新处理方法
小部件更新处理方法负责从 Zabbix 服务器或任何其他数据源检索更新的数据并将其显示在小部件中。
promiseUpdate() 方法通过检索数据来启动数据更新过程,通常使用 Web 请求或 API 调用。 显示仪表板页面时会调用此方法,之后会定期调用,直到仪表板页面切换到另一个仪表板页面。
以下是大多数 Zabbix 原生小部件使用的 promiseUpdate() 方法的默认实现示例。
在默认实现中,promiseUpdate() 方法遵循从服务器检索数据的一般模式。
它使用适当的 URL 和请求参数创建一个新的 Curl 对象,
使用 fetch() 方法发送 POST 请求,并使用由 getUpdateRequestData() 方法构造的数据对象,
并相应地使用 processUpdateResponse(response) 或 processUpdateErrorResponse(error) 处理响应(或错误响应)。
此实现适用于大多数小部件,因为它们通常以 JSON 格式检索数据并以一致的方式处理它。
promiseUpdate() {
const curl = new Curl('zabbix.php');
curl.setArgument('action', `widget.${this._type}.view`);
return fetch(curl.getUrl(), {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(this.getUpdateRequestData()),
signal: this._update_abort_controller.signal
})
.then((response) => response.json())
.then((response) => {
if ('error' in response) {
this.processUpdateErrorResponse(response.error);
return;
}
this.processUpdateResponse(response);
});
}
getUpdateRequestData() 方法通过从小组件的状态和配置中收集各种属性及其对应的值(小组件标识符、筛选设置、时间范围等),并构造一个数据对象,表示更新请求中需要发送到服务器的信息,从而准备用于更新小组件的服务器请求数据。
此方法仅作为默认的 promiseUpdate() 方法的一部分调用,即在小组件更新过程中调用。
默认实现:
getUpdateRequestData() {
return {
templateid: this._dashboard.templateid ?? undefined,
dashboardid: this._dashboard.dashboardid ?? undefined,
widgetid: this._widgetid ?? undefined,
name: this._name !== '' ? this._name : undefined,
fields: Object.keys(this._fields).length > 0 ? this._fields : undefined,
view_mode: this._view_mode,
edit_mode: this._is_edit_mode ? 1 : 0,
dynamic_hostid: this._dashboard.templateid !== null || this.supportsDynamicHosts()
? (this._dynamic_hostid ?? undefined)
: undefined,
...this._contents_size
};
}
processUpdateResponse(response) 方法用于处理更新请求后从服务器接收到的响应;如果更新过程成功且没有错误,则清除小组件数据,并使用 setContents() 方法显示新内容。
此方法仅作为默认 promiseUpdate() 方法的一部分调用,即在小组件更新过程中调用。
默认实现:
processUpdateResponse(response) {
this._setHeaderName(response.name);
this._updateMessages(response.messages);
this._updateInfo(response.info);
this._updateDebug(response.debug);
this.setContents(response);
}
processUpdateErrorResponse(error) 方法处理更新请求后从服务器收到的响应(如果响应为错误),并显示错误消息。 此方法仅作为默认 promiseUpdate() 方法的一部分调用,即在小部件更新过程中调用。
默认实现:
processUpdateErrorResponse(error) {
this._updateMessages(error.messages, error.title);
}
setContents(response) 方法会在 widget 更新过程成功且未发生错误时显示 widget 内容,其中可以包括操作 DOM 元素、更新 UI 组件、应用样式或格式等。
此方法仅作为默认的 processUpdateResponse(response) 方法的一部分调用,也就是说,它会在处理更新请求后从服务器接收到的响应时调用。
默认实现:
setContents(response) {
this._body.innerHTML = response.body ?? '';
}
展示修改方法
小部件展示修改方法负责修改小部件的外观。
onResize() 方法负责调整小组件的视觉元素,以适应新的小组件尺寸。这可能包括重新排列元素、调整元素尺寸、截断文本、实现延迟加载以提高调整大小期间的响应速度等。
当小组件大小发生变化时会调用此方法,例如用户手动调整小组件大小,或浏览器窗口大小发生变化时。
示例:
onResize() {
if (this.getState() === WIDGET_STATE_ACTIVE) {
this._startUpdating();
}
}
hasPadding() 方法负责在小部件配置为 显示其标题 时在其底部应用 8px 垂直填充。
当仪表板页面被激活时,即当它成为用户界面中显示的页面时,将调用此方法。
默认实现:
hasPadding() {
return this.getViewMode() !== ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER;
}
对于某些小部件,需要使用所有可用的小部件空间来配置,例如,自定义背景颜色。 以下是 Zabbix-native Item value 小部件中使用的 hasPadding() 方法的实现示例。
hasPadding() {
return false;
}