首页 > 代码库 > 05WAB入门-Widget开发

05WAB入门-Widget开发

命名规范

实例地址:http://www.arcgis.com/apps/webappviewer/index.html?config=sample-configs/config-demo.json
Widget类    Widget.js
Widget模板    Widget.html
Widget配置    config.json
Widget i18n    nls/strings.js
Widget style    css/style.css
Widget icon    images/icon.png
Widget manifest file    manifest.json

In-panel 和 Off-panel

支持两种类型的widget:in-panle和off-panel。
在编码之前,需要先确定你要开发的widget是否需要一个panel。
它们的区别在于:
1. off-panel不需要在panel中打开,而in-panel是需要在一个panel中打开的。
2. off-panel当配置为一个on-screen微件的时候,存在一个closeable属性,如果将这个属性置为true,则会有一个eye icon控制其显示。
3. off-panel不能放入一个group中。
每个widget都有一个openAtStart控制其是否初始打开。 

部署widget

1. 打开manifest.json。
2. 相应的修改属性。
3. 将widget文件夹粘贴到widget仓库 /client/stemapp/widgets 以及 /client/stemapp3d/widgets
这样你的widget对builder来说就是可行的。
如果你想单独为某一个app部署widget,你可以在下载后的app包里面放置widget,并且修改app.config文件。

所需文件

最少情况下,一个widget相应两个文件,一个js文件以及manifest文件。
然而对于完整功能的widget来说,有许多文件需要定义,比如html模板、i18n、style等等。
技术分享
Widget.js描述了widget
Widget.html 定义widget的UI
config.json 是widget的配置文件
manifest.json 描述了部署属性
nls/strings.js 是国际化所使用到的文件
css/style.css 则是样式文件

Widget manifest

技术分享

属性类型描述是否必须默认值
namestringwidget的标识名称,需要与widget文件夹的名称一致
2Dboolean确定widget是否支持2DTrue
3Dboolean确定widget是否支持3DFalse
platformstring2DWidget必须是HTML 3DWidget必须有是HTML3D
versionstringwidget的版本号
authorstringwidget的作者
descriptionstringwidget的描述
copyrightstringwidget的copyright
licensestringwidget的license
wabVersionstringWAB的版本号,浏览器调试工具控制台输入wabVersion即可获取
propertiesObject参看属性表
featureActionsArray技术分享
属性类型描述是否必须默认值
inPanelboolean设置widget是否inPanel,如果不在一个panel中,widget会直接展示True
hasLocaleboolean设置为true的话,默认加载i8n文件,反之不加载
True
hasStyleboolean设置为true的话,默认加载css文件,反之不加载
True
hasConfigboolean设置为true的话,默认加载config文件,反之不加载True
hasUIFileboolean设置为true的话,默认加载widget.html文件,反之不加载True
hasSettingPageboolean设为为true的话,builder会加载setting页。如果为false并且widget可配置则展示一个Json编辑器True
hasSettingUIFileboolean设置widget是否有settingUi文件True
hasSettingLocaleboolean设置widget的配置页是否支持i18nTrue
hasSettingStyleboolean设置widget的配置页是否有样式True
isControllerboolean设置widget是否是一个控制器False
keepConfigAfterMapSwitchedbooleanbuilder使用,当设置为false时候,builder会在地图改变的时候清除widget的配置True
hasVersionManagerboolean设置widget是否有VersionManager.js,可参看向后兼容一节False
supportMultiInstanceboolean用户是否可以对相同的widget进行多实例True

扩展BaseWidget

技术分享

所需属性

在widget.js中基础的类属性是必须的,它是widget的根元素的类名
技术分享

定义模板

在widget.html中使用html定义模板的结构
修改stemapp/sample-configs文件夹下的config-demo.json文件,找到widget节,增加
技术分享
启动测试地址http://[your host]/webappviewer/?config=sample-configs/config-demo.json即可查看效果。
默认情况下,widget模板不支持dijits。

使Widget可配置

要使widget可配置,需要两个步骤
1. widget中有一个配置文件config.json
2. 配置manifest.json文件中的properties. hasConfig 为true
而在Html模板中使用配置文件中的数据的话,可以使用${config.configField} 其中configField就是json文件中的key值。
而在widget.js文件中,同样可以使用this.config.configField访问到配置的数据。

i18n支持

Widget css支持

需要在写的类的增加上widget的名称。
技术分享

访问map对象

WAB是一款以地图为中心的应用。在BaseWidget类中提供了一个map属性,通过该属性可以访问map对象。
当一个widget实例化的时候,map对象已经传递到实例。所以,同样也可以在postCreate或者startup方法里面访问map对象。
在3Dwidget中,map属性被替换为了sceneView,可以通过this.sceneView访问scene对象。

与App container交互

widget从本质上来说是一个Dojo dijit widget。因此当一个widget实例化的时候,它跟Dijit widget有一样的生命周期。
比如constructor,postCreate,startup。
除了Dojo dijit 的生命周期函数外,widget还有其他的一些回调可以使用。
属性描述
onOpen当widget每次打开的时候都会调用,当widget实例化后,该方法在startup后被调用
onMaximize当widget每次最大化时候被调用,这个方法可能不会被那些面板上没有最大最小状态的widget调用到
onClose当widget关闭的时候调用
onSignIn当登录portal或者ArcGis Online时调用
onSignOut当登出portal或者ArcGis Online时调用
onPositionChange当widget的位置改变时调用。
resize当窗口resize的时候调用
onNormalize不确定
onActive当widget激活时调用,一个widget激活就是指用户点击它的时候
onDeActive当widget失去激活时调用,点击其他widget则可导致当前激活widget失去激活
setPosition在直接显示在屏幕上的widget打开之前调用。
getPanel返回widget的panel,对于off-panel的widget,返回null

Widget属性

名称描述
idwidget在config.json中设置或者由app container生成的唯一的id
iconwidget的图标url
configwidget的config对象
mapmap对象
sceneViewscene对象
appConfigapp的config.json
folderUrlwidget的文件夹url
statewidget的当前状态,active、opened、closed
windowStatewidget的当前窗口状态,normal、maximized、minimized
positionwidget的位置,对于on-screen widget来说非常重要

响应式Widget

jumu.js不仅仅支持响应式的UI布局,而且还提供了开发响应式widget的功能。
有两种方式实现响应式,css和layout dijit
css:jimu.js/css/jimu.css
技术分享
layout dijit:jimu.js/dijit
TileLayoutContainer  
如果这些都不能满足你的需求,可以采用响应式UI的最佳实践。

Widget之间交互

BaseWidget支持在widget之间进行读取和发送数据。在BaseWidget类中,publishData,dataFetched,noData事件都是订阅好的。
BaseWidget同样还提供publishData和fetchData方法。
如果你想从一个widget发布数据,可以调用publishData方法。
如果你想从一个widget接受来自另外的widget的数据,可以调用fetchData方法,并且重写onReceiveData和onNoData来读取数据。
所有发布的数据都存在数据中心DataManager中。所以,widget可以在加载之前接收到被发布的数据。
比如:widgetB 要读取来自 widgetA的数据。在widgetB加载之前,由widgetA发布的数据存储在了数据中心DataManager。当widgetB
加载后,它会调用fetchData方法来取回存储在DataManager中的数据。当widgetB加载完成后,它接受所有赖在widgetA的发布数据。
同理:你或许想再发送消息到一个widget之前,使用this.openWidgetById方法打开它。
可以参照/client/stemapp/widgets/samplewidgets文件夹中widget交互的例子
Tips:从WAB2.1版本开始,你可以在widget之间传递feature set了。
技术分享
名称参数
publishDatadata:要发布的数据
keepHistory:如果是true,则所有发布数据存储在DataManager中(可能导致内存问题),反之,只存储最后一次的数据,默认值为false
fetchDatawidgetid:想要从其获取数据的widget的ID,如果不传入,则取回所有数据,可以在app的config.json中看到所有的widget的id
fetchDataByNamewidgetName:想要从其获取数据的widget的name
onReciveDatawidgetName:发布数据的widget的name
widgetId:发布数据的widget的Id
data:数据
historyData:widget发布的历史数据,有三种参数:undefined 无历史数据 true 存在历史数据,如果想要获取,调用fetchData方法 object 历史数据
TODO:具体实践待补充

使用dojo dijit

widget本身是一个源于BaseWidget dijit的 dojo dijit。因此,可以使用常规的dijit,但是由于性能的原因,不要在BaseWidget中混入_WidgetsInTemplateMixin。
详情参考dojo

使widget在builder中可配置

如果widget是可配置的话,是可以通过修改config.json文件来改变widget的行为的。
最佳实践是,如果一个widget可配置,就需要提供一个配置UI,让其可以在WAB的builder中配置自己。
请遵循下面widget的约定:
1. 创建一个setting文件夹存储相关的设置文件。
2. Setting.js负责维护配置逻辑。这个类继承自BaseWidgetSetting类,在这个类中可以通过config属性条用到widget的config数据。
3. Setting.js需要覆盖两个方法:getConfig-返回用户输入的config数据 setConfig-使用config数据初始化widget的设置页面。
4. 创建一个Setting.html维护config的UI。
5. 创建nls/strings.js,维护设置的本地化。
6. 创建css/style.css,维护config页面的样式。
开发过程中,使用http://host/webappbuilder/?id=stemapp 直接访问widget。这个地址可以测试widget的配置页面。
要查看2Dapp,可以使用http://host/webappviewer/ 加载stemapp。
TODO:具体实践待补充

使widget向后兼容

widget的配置是存储在app中的。当一个widget升级新的功能的时候,有可能需要修改配置的格式。
要想保证widget的配置兼容以前的配置,需要做到两点:
1. 用程序的方式检查配置格式
2. 使用VersionManager去升级旧的格式。

在manifest.json中需要设置
技术分享
创建新的VersionManager.js文件
技术分享
使用BaseVersionManager时需要注意:
1. 由于BaseVersionManager同时运行于浏览器和Node.js,但是由于dojo的类并没有导入node.js,所以不能使用dojo的类。
2. 要把所有的版本放到versions属性中。
3. 在upgrader方法中,输入是旧的configuration,输入是新的configuration
TODO:具体实践待补充

创建controller widget

控制器widget指的是可以控制在widget池中的那些widgets的widget。
HeaderController widget是折叠主题中的一个控制器widget例子。控制器widget通常作为主题的一部分。
控制器widget的创建过程在普通widget创建过程的基础上,增加以下额外步骤:
1. 增加jimu/PoolControllerMixin类,这个类提供了以下方法
方法描述
getWidgetConfigs返回所有在widget池中配置的widget,但是不包含哪些在组中的widget
getGroupConfigs返回widget池中的组
getAllConfigs返回widget池中的组合widget
getConfigById根据ID返回config
在Builder环境下,这个类也提供了一些方法
方法描述
getOpenedIds返回所有打开的widget和组的Ids
setOpenedIds根据传入的参数打开widgets和组
2. 在widget池中基于配置创建一个control menu。
3. 一定要记住,有两种widget,in和offpandel。
TODO:具体实践待补充

widget生命周期

每一个widget都被app container也就是框架所管理,并且拥有自己的生命周期。
当app加载或者用户点击按钮时,一个或者多个widgets被加载和打开。对于on-screen widget,
布局管理器要求widget管理器以异步的方式加载这些widget。当widget加载后,布局管理器调用setPosition方法
将widget追加到Dom树里面,并且放置到正确的位置,允许widget管理器打开他们。
技术分享
Tips:只有off-panel widget才会调用setPosition,并且设置到正确的位置。而对于in-panel widget,它的位置是由panel处理的。
技术分享
Tips:如果app在builder环境外加载,widget一旦加载不会被销毁。但是在builder环境下,
widget将在用户配置widget的时候进行销毁和重建。
技术分享
每个widget都有两个属性存储它的状态:state和windowState。
state属性中widget使用三个值标识了widget的生存状态,active、opened、closed
windowState属性中也使用三个值标识了widget的窗口状态,normal、maximized、minimized
Tips:
1. 查看dojo的状态,参考http://dojotoolkit.org/documentation/tutorials/1.10/understanding_widgetbase/index.html
2. 要想改变widget的state和windowState的值,需要使用WidgetManager中的方法https://developers.arcgis.com/web-appbuilder/api-reference/widgetmanager.htm
3. opened状态下,当widget被关闭了,它并不会被移出dom树,而是被隐藏了。
4. 对于windowState状态,某些widdget或许只有一到二个状态。

添加widget的帮助

你的自定义widget也可以像预设的widget一样,天机help文件。
1. 复制你的widget文件夹到widget仓库。
2. 复制help.html到/docs文件夹。
3. 打开位于/client/builder下的widgetHelp.json文件,增加新的key/value。key是widget的name的小写形式,而name是你的help文件的名称
4. 启动node服务器,可以在http://host:3344/webappbuilder/help/xxx.html查看。
5. 打开widget的设置页面,点击跟多,则可以查看help文件了。

在widget中添加feature action

一个功能动作是执行一个功能或者一组功能的代码封装。WAB中提供了许多内置的功能动作。
比如:Zoom To,Export to CSV文件,以及 View in Attribute Table。
可以通过扩展BaseFeatureAction类来创建自定义的功能动作。
TODO:实践如何创建Feature Action 参看:https://developers.arcgis.com/web-appbuilder/guide/create-a-feature-action-in-your-widget.htm






来自为知笔记(Wiz)


05WAB入门-Widget开发