页面树结构
转至元数据结尾
转至元数据起始

引言

接下来要介绍的是DWF表单控件家族中一个“很能打”的成员——超级控件(新版被改名为html),它基本原理是直接将一个完整的html页面,或者是一个vue文件编译成html页面,放到DWF的后端Web服务器中,然后在表单里用iframe方式嵌入画布区里。

图-超级控件用法示意图

这使得超级控件可以将各种的效果嵌入到表单中,比如:日历、词云、地图、甚至三维模型嵌入进去,所以,叫它超级控件,比如这样的效果:

图-利用超级控件嵌入日历

将三维地球嵌入超级控件

还是先举一个例子吧,在DWF内部提供了一个地图控件,但是我们希望显示一个3D地图,比如这样:

图-利用超级控件嵌入三维地球地图

怎么办?这时候就可以用超级控件来做了,好消息是百度地图已经实现了一个三维地球模型的库,只要申请一个百度的开发者账号,并且建立地图应用,就可以获得开启三维地图的秘钥,关于百度开发者授权可参见:

http://lbsyun.baidu.com/index.php?title=FAQ/authentication

获得详细的帮助,申请地图应用成功以后,界面如下所示:

图-获得百度地图开发者授权与秘钥

获得许可以后,即可用下面的代码开启三维地图,如果读者有兴趣也可以去百度地图的示例页面查看三维地图的效果:三维地球

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
	<style type="text/css">
	body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
	</style>
	<script type="text/javascript" src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=????????"></script>
	<title>地球模式</title>
</head>
<body>
	<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
    // GL版命名空间为BMapGL
	var map = new BMapGL.Map("allmap");    // 创建Map实例
	map.centerAndZoom(new BMapGL.Point(118.5, 27.5), 5);  // 初始化地图,设置中心点坐标和地图级别
	map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
	map.setMapType(BMAP_EARTH_MAP);      // 设置地图类型为地球模式
</script>

上述代码本质上是一个html页面,只是在script标签里增加了一个对百度地图和秘钥的标签,然后在最后按照百度地图的API初始化了一个三维地球模式的地图而已。

接下来,在DWF里面建立一个空白页面,将超级控件拖入,设置一下高度,将上述代码拷贝(再次提醒,记得修改第9行的秘钥,进去运行,即可看到下面的效果:

图-超级控件嵌入3D地球演示

在超级控件中访问DWF数据

“切~,不就是一个iframe嵌入嘛,有什么了不起“,一般有点”水平“的前端程序员们都能做。

的确,自超级控件一开始的时候也就是这么一回事,但是....,你可能想简单了,那些一开始好像不怎么复杂的东西,一放到实践中被实际需求按在地上摩擦,你就会发现一堆问题,比如:

  • 我能在操作里给超级控件传递数据吗?
  • 我怎么将数据加载到这个超级控件里?
  • 超级控件能得到表单里的其他控件并且控制他们的行为吗?
  • 超级控件能够在用户点击的时候弹出你DWF的表单吗?

所以,超级控件内部其实还有一些技能,一般细节不做到这个份上,是不会想到滴....,接下来就说一下这些技能,还是举一个例子吧,比如我们希望实现这样的效果:

基于教程中的设备管理系统例子,如果我们希望将设备的经纬度显示到3D地球上,应该怎么做?

这里就需要在超级控件里访问是DWF提供的数据访问DWF的服务了,超级控件提供了:window.parent.dwf_ctx这个全局变量,这个变量的功能和脚本里的this基本一样,读者可以通过下面的链接看到所有dwf_ctx支持的调用和脚本的函数之间的对应关系。

前端脚本和插件开发调用的对应关系

回顾一下,第六章 表单中的事件脚本 中1.2节,介绍了restful api调用方法,这个例子里可以提取设备类“Asset”的所有对象:objects,所以接入的路径为:“/omf/entities/Asset/objects”,设置参数为空,调用方式如下:

let param = {};
this.dwf_axios.post(`/omf/entities/Asset/objects`,param).then(initRes => {
   //在回调中处理
    console.log(initRes.data.data);
});

在超级控件里希望加载所有设备类的对象,就可以这么做:

let param = {};
let ctx = window.parent.dwf_ctx
ctx.dwf_axios.post(`/omf/entities/Asset/objects`,param).then(initRes => {
   //在回调中处理
    console.log(initRes.data.data);
});

可以看到,有了dwf_ctx就可以完成之前说的很多事情了,接下来,将地图中的代码修改成这样:

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
	<style type="text/css">
	body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
	</style>
	<script type="text/javascript" src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=?????"></script>
	<title>地球模式</title>
</head>
<body>
	<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
    // GL版命名空间为BMapGL
	var map = new BMapGL.Map("allmap");    // 创建Map实例
	map.centerAndZoom(new BMapGL.Point(118.5, 27.5), 5);  // 初始化地图,设置中心点坐标和地图级别
	map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
	map.setMapType(BMAP_EARTH_MAP);      // 设置地图类型为地球模式
	
	var ctx = window.parent.dwf_ctx;
	let param = {};
    ctx.dwf_axios.post(`/omf/entities/Asset/objects`,param).then(initRes => {
      //在回调中处理
      console.log(initRes.data.data);
      let assets = initRes.data.data;
      assets.forEach(a => {
          var marker = new BMapGL.Marker(new BMapGL.Point(a.locationX, a.locationY));
          // 在地图上添加点标记
          map.addOverlay(marker);
      });
    });
</script>

就可以看到如下的效果:

超级控件里调用DWF表单

如果希望点击地图上的标记点打开DWF表单呢?

这也不难,可以利用dwf_ctx的executeOperation完成单击后触发操作。

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
	<style type="text/css">
	body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
	</style>
	<script type="text/javascript" src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=??????"></script>
	<title>地球模式</title>
</head>
<body>
	<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
    // GL版命名空间为BMapGL
	var map = new BMapGL.Map("allmap");    // 创建Map实例
	map.centerAndZoom(new BMapGL.Point(118.5, 27.5), 5);  // 初始化地图,设置中心点坐标和地图级别
	map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
	map.setMapType(BMAP_EARTH_MAP);      // 设置地图类型为地球模式
	
	var ctx = window.parent.dwf_ctx;
	let param = {};
    ctx.dwf_axios.post(`/omf/entities/Asset/objects`,param).then(initRes => {
      //在回调中处理
      console.log(initRes.data.data);
      let assets = initRes.data.data;
      assets.forEach(a => {
          var marker = new BMapGL.Marker(new BMapGL.Point(a.locationX, a.locationY));
          marker.asset = a; //先将标记点对应的数据绑定起来
          marker.addEventListener('click', function () {
                console.log(marker.asset);
				// 单击的时候打开对话框
                let initParams={ obj:marker.asset }; 
                ctx.openForm('Asset','AssetComposition',null,'visit',initParams);              
            });
          map.addOverlay(marker);
        });
    });
</script>

上面的代码中,在初始化标记的时候将设备对象带入机marker.asset = a,然后每个标签里添加了一个click事件,并使用openForm方法打来表单,结果如下所示:

图-点击标签弹出DWF表单

表单控件的收藏打包

最后,除了上面介绍的内容以外,DWF的表单引擎还为超级控件提供了一个收藏打包带走的能力,也就是说,你可以写一个超级控件,收藏起来,然后在其他表单里反复使用它。

图-收藏超级控件

不仅如此,还可以把这个超级控件打包到模型包里,带走或者发给你小伙伴。

图-在模型包内部打包超级控件

注意事项

最后,超级控件虽好,但也不要贪杯,下面看看使用超级控件的时候需要注意的地方:

首先,在超级控件的代码里如果出现了外部依赖,例如:需要某些互联网的内容,那么,超级控件在不能联网的环境下会出现失效,所以使用的时候要注意。

其次,超级控件使用的是iframe嵌入的方式完成展示,不能在表单里滥用,比如,一张表单里放100个超级控件,嵌入100个页面,这种做法可能会导致表单无法使用。


  • 无标签