展示

此页面描述了可用于create widget展示视图的组件。
widget展示视图是widget的一部分,它根据其configuration接收数据,并将其显示在仪表板的容器中。

展示视图由三个部分组成:

小工具操作

widget动作类(WidgetView)包含用于在展示视图模式下操作小部件的方法。
大多数widget动作使用和/或扩展默认控制器类CControllerDashboardWidgetView

widget动作类应位于actions目录中,并在manifest.json文件中的动作参数(actions/widget.{id}.view/class)中指定。

actions/WidgetView.php 示例(在 Zabbix 原生 System information 小部件中实现)

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()
                   ]
               ]));
           }
       }

小部件视图

小部件get视图类(CWidgetView)负责构建小部件get的呈现视图。

小部件get视图类应位于views目录中。 如果包含小部件get视图类的file与默认名称(widget.view.php)不同,则必须在manifest.json的file 动作参数中指定(actions/widget.{id}.view/view)。

views/widget.view.php 示例

<?php
       
       /**
        * My custom widget view.
        *
        * @var CView $this
        * @var array $data
        */
       
       (new CWidgetView($data))
           ->addItem(
               new CTag('h1', true, $data['name'])
           )
           ->show();

JavaScript

JavaScript 类负责确定小部件 get 的行为,例如更新小部件 get 的数据、调整小部件大小、显示小部件 get 元素等。

所有 JavaScript 操作都使用和/或扩展了所有仪表板小部件的基类 JavaScript 类 —— CWidget
CWidget 类包含一组具有默认实现的方法,用于小部件 get 的行为。
根据小部件 get 的复杂程度,这些方法可以直接使用或进行扩展。

CWidget 类包含以下方法:

  • 定义小部件 get 生命周期的方法:onInitialize()onStart()onActivate()onDeactivate()onDestroy()onEdit()
  • 处理更新和显示小部件 get 数据的方法:promiseUpdate()getUpdateRequestData()processUpdateResponse(response)processUpdateErrorResponse(error)setContents(response)
  • 修改小部件 get 外观的方法:onResize()hasPadding()

JavaScript 类应位于 assets/js 目录中,并在 manifest.json 文件的 资产assets/js)参数中指定。

生命周期方法

widget生命周期方法由仪表板调用,并在该控件存在于仪表板中的不同生命周期阶段被触发。

onInitialize() 方法用于定义小部件的初始状态和/或值,而不执行任何HTML或数据操作。 该方法在小部件创建时调用(当小部件实例object被实例化时),通常通过将小部件添加到仪表板页面或加载仪表板页面来触发。

示例:

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() 方法通过启用自定义事件监听器(用于响应用户操作)和启动 widget update 周期(用于保持其内容为最新状态),使 widget 处于活动状态并具有交互性。
此方法在仪表板页面被激活时调用,即当该页面在用户界面中完全显示时。

请注意,在调用 onActivate() 方法之前,widget 处于非活动状态(WIDGET_STATE_INACTIVE)。
成功调用后,widget 将转换为活动状态(WIDGET_STATE_ACTIVE)。
在活动状态下,widget 是响应式的,能够监听事件,定期更新其内容,并可以与其他小部件进行交互。

示例:

onActivate() {
           this._startClock();
       
           this._resize_observer = new ResizeObserver(this._events.resize);
           this._resize_observer.observe(this._target);
       }

onDeactivate() 方法通过停用自定义事件监听器并停止 widget 的 update 周期,来停止该 widget 的所有活动和交互。

当仪表板页面被停用(即切换离开或删除),或当 widget 从仪表板页面中删除时,将调用此方法。

请注意,在调用 onDeactivate() 方法之前,widget 处于激活状态(WIDGET_STATE_ACTIVE)。 成功调用后,widget 将转换为非激活状态(WIDGET_STATE_INACTIVE)。

示例:

onDeactivate() {
           this._stopClock();
           this._resize_observer.disconnect();
       }

onDestroy() 方法在 widget 被从仪表板中删除之前执行清理任务, 这可能包括关闭在 widget 初始化期间建立的数据库连接、 清理临时数据以释放系统 memory 并避免资源泄漏、 注销与调整大小事件或按钮点击相关的事件监听器以防止不必要的事件处理和 memory 泄漏等。 当包含 widget 的仪表板页面被删除时,将调用此方法。

请注意,在调用 onDestroy() 方法之前,处于活动状态(WIDGET_STATE_ACTIVE)的 widget 总是会通过调用 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() 方法定义了仪表板进入编辑模式时小部件的外观和行为get。 当仪表板进入编辑模式时会调用此方法,通常是在用户与小部件的 Edit 按钮或仪表板的 Edit dashboard 按钮交互时触发。

示例:

onEdit() {
           this._deactivateGraph();
       }
更新过程方法

小部件的get update处理方法负责从Zabbix server或其他任何数据源检索更新的数据,并在小部件中显示。

promiseUpdate() 方法通过获取数据(通常使用网络请求或API调用)启动数据update流程。
该方法在仪表板页面显示时被调用,并在之后定期执行,直到切换至其他仪表板页面为止。

以下是大多数Zabbix原生小部件默认实现的promiseUpdate()方法示例。
在默认实现中,promiseUpdate()方法遵循从服务器获取数据的通用模式:
- 使用正确的URL和请求参数创建新的Curl object
- 通过fetch()方法发送POST请求(请求数据object由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()方法通过收集小部件状态和配置中的各种属性及其对应的值(widget标识符、过滤器设置、时间范围等),并构建一个数据object,以表示在update请求中发送到服务器的必要信息,从而准备用于更新widget的服务器请求数据。
此方法仅作为默认的promiseUpdate()方法的一部分调用,即在widget的update过程中调用。

默认实现:

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)方法处理在update请求之后从服务器接收到的响应,并且,如果update过程成功且无错误,则清除widget数据并使用setContents()方法显示新内容。
此方法仅作为默认promiseUpdate()方法的一部分调用,即在widget update过程中调用。

默认实现:

processUpdateResponse(response) {
           this._setHeaderName(response.name);
       
           this._updateMessages(response.messages);
           this._updateInfo(response.info);
           this._updateDebug(response.debug);
       
           this.setContents(response);
       }

processUpdateErrorResponse(error) 方法用于处理从服务器接收到的 update 请求响应,如果响应为错误,则显示错误消息。 此方法仅作为默认的 promiseUpdate() 方法的一部分调用,即在 widget update 过程中调用。

默认实现:

processUpdateErrorResponse(error) {
           this._updateMessages(error.messages, error.title);
       }

setContents(response) 方法用于在 widget 的 update 过程成功且无错误时显示 widget 内容,
这可能包括操作 DOM 元素、更新 UI 组件、应用样式或格式等。
该方法仅作为默认的 processUpdateResponse(response) 方法的一部分被调用,即在处理从服务器接收到的 update 请求响应过程中调用。

默认实现:

setContents(response) {
           this._body.innerHTML = response.body ?? '';
       }
展示修改方法

widget 的呈现修改方法负责修改 widget 的外观。

onResize() 方法负责调整小部件的视觉元素以适应新的 widget 尺寸,
这可能包括重新排列元素、调整元素尺寸、文本截断、在调整大小期间实现延迟加载以提高响应能力等。
当 widget 被调整尺寸时,例如用户手动调整 widget 尺寸或浏览器窗口尺寸发生变化时,将调用此方法。

示例:

onResize() {
           if (this.getState() === WIDGET_STATE_ACTIVE) {
               this._startUpdating();
           }
       }

hasPadding() 方法负责在小部件配置为 通用参数 时,在其底部应用 8px 的垂直内边距 widget。

当仪表板页面被激活,即在用户界面中成为显示页面时,将调用此方法。

默认实现:

hasPadding() {
           return this.getViewMode() !== ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER;
       }

对于某些小部件,需要使用所有可用的 widget 空间进行配置,例如自定义背景颜色。 以下是 Zabbix 原生 Item value 小部件中使用的 hasPadding() 方法的实现示例。

hasPadding() {
           return false;
       }