展示

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

展示视图由三部分组成:

小工具操作

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

部件操作类应位于actions目录中,并在manifest.json file的动作参数(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()
                   ]
               ]));
           }
       }

小部件视图

部件视图类(CWidgetView)负责构建部件的展示视图。

部件视图类应位于views目录中。 如果包含部件视图类的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类负责确定小部件行为,例如更新小部件数据、调整小部件大小、显示小部件元素等。

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

CWidget类包含以下方法:

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

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

生命周期方法

小部件的生命周期方法由仪表板调用,并在小部件存在于仪表板期间的不同生命周期阶段被触发。

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

请注意,在调用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() 方法通过停用自定义事件监听器并终止小部件的update周期,停止小部件的所有活动和交互性。 该方法在仪表板页面停用时(即切换离开或删除时)或从小部件从仪表板页面删除时调用。

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

示例:

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

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

注意在调用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() 方法定义了当仪表盘进入编辑模式时小部件的外观和行为。 该方法在仪表盘进入编辑模式时被调用,通常发生在用户与小部件的编辑按钮或仪表盘的编辑仪表盘按钮交互时。

示例:

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

该小部件update处理方法负责从Zabbix server或其他数据源获取更新数据并在小部件中显示。

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

以下是大多数Zabbix原生小部件使用的promiseUpdate()方法默认实现的示例。 在默认实现中,promiseUpdate()方法遵循从服务器获取数据的通用模式。 它创建一个新的Curl object,包含适当的URL和请求参数, 使用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() 方法通过从部件状态和配置中收集各种属性及其对应值(部件标识符、筛选设置、时间范围等),为更新部件准备服务器请求数据, 并构建一个表示需要发送至服务器的必要信息的 object 数据结构,用于 update 请求。 此方法仅作为默认的 promiseUpdate() 方法的一部分被调用,即在部件 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进程成功且无错误,则会清除部件数据并通过setContents()方法显示新内容。 此方法仅作为默认promiseUpdate()方法的一部分被调用,即在部件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) 方法用于在部件update处理过程成功且无错误时显示部件内容, 该过程可能包括操作DOM元素、更新UI组件、应用样式或格式化等。 此方法仅作为默认processUpdateResponse(response)方法的一部分被调用,即在处理来自服务器的update请求响应过程中执行。

默认实现:

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

小部件呈现修改方法负责调整小部件的外观显示。

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

示例:

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

hasPadding() 方法负责在部件配置为通用参数时,在部件底部应用8像素的垂直内边距。 该方法在仪表板页面激活时被调用,即当该页面成为用户界面中显示的页面时。

默认实现:

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

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

hasPadding() {
           return false;
       }