添加远程控制

独立开发者暂不支持上传终端交互组件

远程控制提供一种方式,使组件可以控制其他大屏的事件和交互。大屏的最终展示载体通常是由多块屏幕拼接而成的巨型屏幕,这种场景下想要和大屏交互,使用鼠标和键盘显然不像操作pc那么方便,打造大屏专用的控制终端(比如手机、pad)显然是更加便利和合理的方案,想象一下你在看电视的时候使用遥控器肯定比跑到电视机下面按按钮来的方便,远程控制终端就是大屏的遥控器,而远程控制终端界面就是由1个或多个带有远程控制功能的组件组成的小屏。

本教程将说明如何为组件添加远程控制的功能,远程控制分为2种,设置远程回调和绑定远程事件,下面会分别说明,本文只展示必要的步骤,我们假定你已经阅读过快速入门或已经了解组件开发流程,你也可以下面底部的源码来帮助理解。


1. 添加控件

为了添加远程控制控件,我们在config/main.json中加入以下配置。

{
  ...
  "configuration": [
    {
      "name": "interaction",
      "displayName": "交互",
      "value": [
        {
          "name": "callback",
          "displayName": "回调参数",
          "type": "array",
          "value": [],
          "config": {
            "template": [
              {
                "name": "callback",
                "displayName": "回调",
                "type": "object",
                "value": [
                  {
                    "name": "origin",
                    "displayName": "字段值",
                    "type": "input",
                    "value": ""
                  },
                  {
                    "name": "target",
                    "displayName": "变量名",
                    "type": "input",
                    "value": ""
                  }
                ]
              }
            ]
          }
        },
        {
          "name": "remoteControl",
          "displayName": "远程控制",
          "type": "array",
          "value": [],
          "config": {
            "template": [
              {
                "name": "controls",
                "displayName": "控制",
                "type": "object",
                "value": [
                  {
                    "name": "control",
                    "displayName": "控制",
                    "type": "remoteOptions",
                    "value": "{}"
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  ]
}

上面的配置中,我们添加了一个name为interaction的配置对象,interaction为平台保留属性值,表示定义的是交互配置,这些配置不会出现在组件的样式面板中,而是被放到交互面板中。接着给交互添加了2个配置组,第1个为回调组列表,回调可以理解为组件将内部的数据暴露给外部使用,第2个为远程控制组列表,该控件对象的name必须为 remoteControl,其内部包含一个remoteOptions控件对象,该控件会由平台动态加载其他大屏、组件、动态面板、自定义事件作为选项值,用户关联好要操控的大屏事件后,通过组件内部的代码关联,调用平台的接口来绑定其他大屏的交互事件

注意:

remoteOptions只能定义在终端交互的组件中,大屏不支持远程控制其他大屏


2. 远程回调

远程回调和普通回调(如何编写普通回调?)的区别是,普通回调是把组件的数据暴露给外部其他组件使用,远程回调的作用是把组件的数据暴露给其他大屏里的组件使用,跟普通回调一样,用户要先设置需要暴露的字段,然后将remoteOptions的类型设置为回调,然后选择需要暴露给哪个大屏。

用户这样设置以后,组件需要通过平台接口将数据暴露出去,参考以下代码

const handleRemoteInteract = () => {
  const remoteControls = Object.keys(interaction.remoteControl).map((key) => interaction.remoteControl[key]);
  remoteControls.map((o) => {
    const control = JSON.parse(o.control);
    if (!control.type) return;
    if (control.type === 'callback') handleRemoteCallback(control);
  });
}

const handleRemoteCallback = control => {
  // control对象结构: {
  //  screen: "$screen(243)"
  //  type: "callback"
  // }
  
  // 获取回调映射表
  let callbackData = {};
  Object.values(interaction.callback).map((d) => {
    callbackData[d.target] = data[0][d.origin];
  });
  // 发送回调到远程大屏
  emitEvent({
    screen: control.screen,	// 大屏id
    type: 'callback',
    callbackData,	// 要暴露的数据
  });
}

return (
  <div ... onClick={handleRemoteInteract}>
    点我触发远程控制
  </div>
);

我们预期当用户点击组件的时候,触发远程回调,为此我们添加了一个onClick事件,事件中经过遍历和解析,得到每个远程控制的类型control.type,这对应我们在平台上设置的remoteOptions控件的类型,判断类型为回调后,调用远程回调函数。

在远程回调函数中,先收集用户要暴露出去的数据属性,将其映射到一个新的数据对象callbackData的新属性中,这和普通回调类似,区别是远程回调最后要通过emitEvent接口,关联远程大屏id和回调数据,告诉平台要将数据暴露给哪个大屏。


3. 远程事件

远程事件用于触发大屏中已经设置好的自定义事件(如何编写自定义事件?),其逻辑流程是,通过remoteOptions控件获取设置好的自定义事件对象,然后通过emitEvent接口通知平台触发相应的大屏事件

需要注意的是,目前远程控制事件只支持一些基础的事件类型,组件的自定义事件类型暂时不支持,只支持所有组件都默认集成的几种事件类型。

在这次操作中,用户绑定了名为test1的大屏中的交互事件demo组件中已经设置好的鼠标单击事件,为了实现事件的绑定,我们需要在代码中处理绑定关系,参考以下代码。

const handleRemoteInteract = () => {
  const remoteControls = Object.keys(interaction.remoteControl).map((key) => interaction.remoteControl[key]);
  remoteControls.map((o) => {
    const control = JSON.parse(o.control);
    if (!control.type) return;
    if (control.type === 'event') handleRemoteEvent(control);
  });
}

const handleRemoteEvent = control => {
  // control对象结构: 
  // {
  //  component: "$component(27387)"
  //  event: "{"type":"click","delayed":0,"action":"show/hide","page":"","component":"$component(27386)","panel":"{}","animationName":"fade","duration":600}"
  //  screen: "$screen(243)"
  //  type: "event"
  // }

  const originEvent = JSON.parse(control.event);	
  let eventData;
  switch (originEvent.action) {	// action为要控制的组件的事件类型
    // 隐藏
    case 'hide': {
      if (!originEvent.component) return;
      eventData = {
        component: originEvent.component,		//受控组件的id
        state: { show: false },							//组件状态
        activeState: {										
          animation: {											//组件动作对象
            key: 'show',										//动作id
            ...getAnimation(originEvent), 	//动作对象的其他属性
          },
        },
      }
    } break;
  }

  emitEvent({
    screen: control.screen,
    ...eventData
  });
}

return (
  <div ... onClick={handleRemoteInteract}>
    点我触发远程控制
  </div>
);

首先给组件添加onClick事件,当组件点击时,获取用户配置的远程控制的参数,如果配置的是事件,则调用远程事件函数。

在远程事件函数中,先解析受控组件的事件control.event,再根据事件对象的action属性判断事件类型,将其封装成平台能够识别的固定对象结构eventData,其中component属性为受控组件id,state属性为组件显隐等状态信息,activeState.animation为事件执行的具体动作的动作对象,其key为动作id,通过getAnimation获取事件对象的其他动作属性。

要使用getAnimation,可通过npm i -g @easyv/utils命令安装对应包

显示、隐藏、显隐切换、组件状态切换这些动作由平台默认添加,具体的实现请查看文章最后的源码。

最终通过emitEvent接口关联远程大屏id和封装好的事件对象eventData,告诉平台触发哪个大屏的相应事件。

使用组件

将该组件发布终端交互后,即可新建终端交互大屏使用。终端大屏预览时,在PC端不支持操作,需要扫描二维码进入终端设备进行控制。


4. 其他

示例源码下载

如遇其他使用问题,可扫描下方二维码,获取更多产品支持~

400-8505-905复制
免费试用
在线咨询
微信社区
易知微-数据可视化
微信扫一扫入群