跳至主要內容

组件交互

黄健大约 9 分钟进阶使用

组件交互主要涉及数据交互(数据钻取、数据联动)、DOM交互等。

PageNow中提供了两种方式实现数据交互:事件总线、内直数据交互流,对于DOM交互,可以通过编辑原生JS或使用JQuery来操作。

DOM交互

PageNow内置了JQuery,具体JQuery的版本,可以前往 API-$ 查看,大部分情况下我们都可以通过使用JQuery去操作页面中的DOM元素,当然,如果对原生JavaScript更熟悉的,也可以不使用JQuery,我们只是提供多一种选择。

下面通过一些简单的示例说明如何进行一些基本的DOM操作:

示例1:控制单个组件的显隐

操作步骤如下:

  1. 先获取图表组件的布局块ID【e4a25c8cfdfe6f4a00ff00828dccec87】,需要注意:一般我们在进行DOM操作时,如果是需要使用ID去获取DOM节点,应该获取的是组件所属布局块的ID,而不是组件ID

  2. 在按钮组件的【交互】-【鼠标单击时运行脚本】中添加如下代码

    $('#e4a25c8cfdfe6f4a00ff00828dccec87').toggle()
    

示例2:控制多个组件的显隐

此示例中,要求点击按钮之后,同时控制边框组件和柱状图组件的显示隐藏。

实现方式一:

与示例1中的操作同理,我们可以复制边框组件所属布局块的ID与柱状图组件所属布局块的ID,然后在按钮组件的交互脚本中添加如下代码:

// 操作边框组件的显隐
$('#105638b80a960d47baf8ce9cb2828c1f').toggle()
// 操作状图组件的显隐
$('#e4a25c8cfdfe6f4a00ff00828dccec87').toggle()//JQuery的选择器的使用方式的区别
$('#105638b80a960d47baf8ce9cb2828c1f,#e4a25c8cfdfe6f4a00ff00828dccec87').toggle()

实现方式二:

实现方式一中是通过ID去查询DOM节点,当我们需要控制的组件显隐的数量比较多时,通过ID的方式就不方便,组件所属布局块中可以给布局块定义自定义Class,基于Class查询多个DOM节点则比较方便, 那么我们给边框组件和柱状图组件都定义Class名称为 toggle-div

然后在按钮组件的交互脚本中添加如下代码:

$('.toggle-div').toggle()

事件总线

PageNow的事件总线本身就是基于VUE的事件总线EventBus去实现事件的分发,通过在发起事件总线事件时携带回调参数来实现组件之间的数据交互。

虽然通过事件总线的方式实现组件交互,需要用户具备一定的前端编程基础,但事件总线方式,也是最灵活的一种方式。

下面将通过一个【Tab列表组件与多行文本组件之间的数据交互】示例来说明如何使用事件总线:

如上图所示,其中多行文本组件中的数据是通过API接口请求获取的数据,我们需要在用户点击Tab列表中的某项之后,改变多行文本组件的API请求参数。

首先多行文本组件的API接口地址为:

http://localhost:8090/test/getText?str=hello

接口返回的数据为:

[
    {
      "value": "我是接口返回的数据,接收的参数:hello"
    }
]

操作步骤如下:

  1. 发送总线事件

在Tab列表组件的【交互】-【点击标签项时触发】的脚本编辑框中添加如下代码

// 强烈推荐用法
EventBus.send("clickTabItem",value)
或
EventBus.$emit("clickTabItem",value)

当每一次点击Tab列表组件中的项时,就会执行以上代码,用于发送一次事件总线事件,事件名称为 clickTabItem ,事件总线名称可以任意命名(注意:虽说可以任意命名,但不可携带字符串pn_,因为此字符已经被平台内部占用), 发送的数据为 value ,value 中存储的是Tab列表组件被点击的项的数据,需要注意,Tab列表组件的这个 value 存储的是一个数组。

  1. 接收总线事件

在多行文本组件的【交互】-【初始化运行脚本】的脚本编辑框中添加如下代码

// 强烈推荐用法
EventBus.receive(["clickTabItem"], (params) => {
  this.component.compConfigData.ds_apiPath = "http://localhost:8090/test/getText?str="+params[0]
  this.redrawComp()
})
或
EventBus.$on(["clickTabItem"], (params) => {
  this.component.compConfigData.ds_apiPath = "http://localhost:8090/test/getText?str="+params[0]
  this.redrawComp()
})

此代码在多行文本组件初始化阶段,通过 EventBus.receive 监听了名称为 clickTabItem 的事件总线事件,回调函数中通过 this.component.compConfigData.ds_apiPath=... 去动态的修改了组件的API接口地址,然后执行 this.redrawComp() 对组件进行重绘。

注:当我们去动态修改组件的数据源相关的配置(ds_apiPath、ds_apiHeaders、ds_apiPostData、ds_sql...等)后,都要执行一次重绘操作来使用新的配置进行数据请求。

初始化运行脚本中特有变量

大部分情况下,在组件初始化运行脚本中有以下几个特定的属性变量:

  • original_ds_apiPath:当组件能够使用API数据源,那么此变量存储组件原始的(或者叫首次请求的)API接口地址
  • original_ds_sql:当组件能够使用直连数据库数据源,那么此变量存储组件原始的(或者叫首次请求的)SQL语句
  • original_ds_resultObj:当组件可以配置数据源结果集,那么此变量存储组件原始的(或者叫默认绑定)的数据源结果集

初始化运行脚本中特有变量的作用说明

在讲解事件总线的使用章节中,接收事件总线事件的代码段里,我们看到以下这么一段代码

this.component.compConfigData.ds_apiPath = "http://localhost:8090/test/getText?str="+params[0]

这段代码的作用是根据接收到的事件总线传过来的参数去动态修改组件的API接口地址,这里边存在一个问题:我们在动态修改地址的过程中,对整个地址都进行了重新赋值!某些情况下可能我们不想要这样做,而是在原本的API地址之后添加新的参数或拼接新的字符, 我们将多行文本组件的API接口地址改为 http://localhost:8090/test/getText ,默认不携带参数str参数,然后总线接收代码的编写改为如下所示:

EventBus.receive(["clickTabItem"], (params) => {
  this.component.compConfigData.ds_apiPath = original_ds_apiPath + "?str=" + params[0]
  this.redrawComp()
})

内置数据交互流

相比于事件总线的方式,内置数据交互流更为方便快捷,且无需具备太多编程基础即可实现组件之间的数据交互,但为了让编程人员更为灵活的去使用内置交互流,我们还是贴心的为内置数据交互流实现了两种使用方式:一种是【纯配置化方式】,另外一种是【通过脚本手动发起方式】

我们还是通过事件总线中的示例来讲解内置交互流的使用方法。

纯配置化方式

一次内置交互流必须具备发送端和接收端,在示例中,Tab列表组件作为发送端发送内置交互流,多行文本组件则作为接收端接收内置交互流

发送端

我们在Tab列表组件的【交互】-【点击标签项时触发】中进行如下配置

发送方要发送内置交互流,必须勾选上【开启发送权限】,然后配置【绑定到交互变量】,目的是将组件的value值绑定到内置交互流上的特定变量上,这个变量名称必须不能与数据源字段同名,如果上图配置中,我们将value数据源字段绑定到了tabValue交互变量上, 当Tab列表组件的标签项点击时,就会发起一次内置交互流,此交互流中则会将标签项的value值绑定到tabValue变量上发送出去。

接收端

接收端要接收内置交互流,首先需要在【交互】-【内置数据交互流】中勾选【开启接收权限】

开启接收权限后,我们就可以在组件的API接口地址中通过{{}}语法去读取内置交互变量,下面我们将多行文本组件的API接口地址做如下修改

http://localhost:8090/test/getText?str={{tabValue|hello}}

其中tabValue对应的就是Tab列表组件中配置的tabValue变量名,而|中下划线后面的字符则代表默认值

为什么会使用中下划线设置默认值?

一般情况下,内置交互流属于主动触发,也就是当页面加载完成后,在用户没有进行任何组件的交互操作之前, 是不会发起内置交互流的,那么这个时候,当多行文本组件的API接口地址中使用到了内置交互变量tabValue时,首次加载是读取不到tabValue中有任何值的,这时候就可以使用中下划线来给接口地址设置一个默认请求的值

通过以上的配置,即完成了Tab列表组件与多行文本组件之间的内置交互流数据交互了,当我们点击Tab列表项时,Tab列表会发起一次内置交互流,由于多行文本组件中开启了内置交互流的接收权限,并且在API接口地址中配置了{{}}语法读取了交互流变量,那么系统会自动为多行文本组件使用接收到的内置交互变量对组件进行重绘操作。

通过脚本手动发起方式

PageNow中提供了工具函数 PnUtil.manuallaunchinteractionstream() 来实现脚本方式发起内置交互流,使用方式与纯配置化的方式区别在于发送端,接收端不需要变动,发送端关闭【内置数据交互流】中的发送权限

然后在【点击标签项时触发】中的脚本编辑框中添加如下代码即可:

PnUtil.manualLaunchInteractionStream("tabValue",value[0])

与配置化的方式同理,manualLaunchInteractionStream函数中第一个参数为绑定的交互变量名,第二个参数则是变量值,至于为什么是 value[0],因为前面章节已说明过,Tab列表中【点击标签项时触发】的脚本中,通过value获取的值是一个数组,在纯配置化方式中,系统默认处理了这个数组值。