版权所有IBM公司2007商标使用Dojo和WebSpherePortal实现客户端InterportletCommunication第1页,共10使用Dojo和WebSpherePortal实现客户端InterportletCommunicationAronWallaker(wallaker@ca.
ibm.
com)IT专家,IBMSoftwareServicesforWebSphereEMC2007年8月14日本文将描述如何使用DojoJavaScript工具包将客户端InterportletCommunication添加到IBMWebSpherePortal(以下称为WebSpherePortal)Portlet.
本文专为特定开发人员撰写,这些开发人员开始结合使用Ajax和WebSpherePortal,并希望在客户端复制他们以前已在服务器端上实现的InterportletCommunication.
在学习本文时,为获得最好的效果,您应该已经对JavaScript编程、WebSpherePortal和Portlet开发等内容有很好的了解.
有关有助于获得这些知识的参考,请参见参考资料.
本文的示例Portlet应用程序是使用IBMRationalApplicationDeveloperv7进行开发的,并且已在WebSpherePortalV6.
0上进行了测试.
引言许多门户开发人员已使用WebSpherePortal创建用于共享事件和数据以增强用户体验的协作Portlet.
例如,在一个Portlet中提交的选择可导致更新的信息在多个相关的Portlet中显示,从而有助于这些Portlet在其表示中保持同步.
此功能在服务器上实现,依赖于Portlet将操作请求提交到服务器,以使该服务器可以在页面被刷新之前执行数据传输.
然而,当您将Ajax功能添加到Portlet时,此方法就变得无人问津了,因为Ajax功能使您可以动态更新由Portlet显示的数据,而不用提交操作请求或刷新页面.
本文将说明如何使用DojoJavaScript工具包在浏览器中共享Portlet之间的数据和事件,该工具包可为动态更新的Portlet提供协作支持.
什么是DojoDojo是开源JavaScript工具包,可用于开发动态Web应用程序.
Dojo的许多库中都包含Ajax支持、DOM操作工具、事件处理系统和可自定义的小部件集.
Dojo将这些库与一个灵活的打包系统组合在一起,这样,您就可以只导入所需的库;Dojo自动地为您解决了所有库与库之间的依赖关系.
使用Dojo动态打包系统正是使用Dojo库与使用传统JavaScript包含的区别所在.
执行两个步骤就可以包括Dojo库.
您将执行以下两个步骤:1.
包括Dojo引导.
developerWorksibm.
com/developerWorks/cn/使用Dojo和WebSpherePortal实现客户端InterportletCommunication第2页,共102.
标识您的应用程序所需要的Dojo库.
您使用dojo.
require语句来包括Dojo小部件的管理功能(dojo.
widget.
*)和Button小部件(dojo.
widget.
Button).
dojo.
require("dojo.
widget.
*");dojo.
require("dojo.
widget.
Button");dojo.
require语句可指定您将要在应用程序中使用的Dojo资源.
Dojo引导将对页面进行扫描以查找这些dojo.
require语句,并且将动态包括对应的库以使这些资源可供使用.
动态加载进程还处理Dojo库之间的所有依赖关系,因此,您只需针对所使用的资源直接添加require语句.
结合使用Dojo和WebSpherePortalDojo的独特加载策略为Portlet开发人员出了一道难题.
Dojo引导dojo.
js只应在HTML页面中包括一次.
取决于浏览器类型,如果包括dojo.
js两次或两次以上,则会导致JavaScript错误并向最终用户报告这些错误.
在WebSpherePortal中避免出现该问题的最简单的方式是:在您的主题的JSP中包括dojo.
js,然后根据需要在您的主题和PortletJSP中放置dojo.
require语句.
然而,我希望读者在学习了示例应用程序后,能够在不需要修改其主题的情况下部署Portlet.
因此,我已在Portlet项目中包括Dojo库,并且用JavaScript编写了条件加载器.
条件加载器包含在dojoLoader.
jsp文件中:varpath="/dojo/dojo.
js";if(typeofdojo=="undefined"){document.
write('');}此代码检查dojoJavaScript对象是否存在,如果未定义该对象,此代码将插入脚本,以便将dojo.
js包括在当前HTML文档中.
用于执行此操作的JavaScript代码不太好理解,因此,必须对字符串形式的或的所有实例进行拆分;否则,某些浏览器会尝试将其解析为脚本的实际的起始及结束语句.
而采用修改主题JSP这一解决方案就会简单很多.
因此,请只在无法修改主题JSP的情况下才使用此条件加载器技术.
使用Dojo事件Dojo包括一个事件通信系统,开发人员利用该系统可以连接应用程序的组件.
传统DOM事件可将事件映射到任何属性、对象或元素,而该功能则超出了此范围;该功能包括了诸如面向方面的编程(AOP)或事件发布/订阅之类的高级功能.
本文将重点讨论事件发布/订阅系统(称为主题),以及如何使用该系统以便在Portlet之间进行通信.
在Dojo事件发布/订阅系统中,可以基于共享主题或队列名称以匿名的方式在组件之间进行通信.
JavaScript组件可使用Dojo事件库来发布或订阅主题.
发布组件可以使用与事件相关的数据创建对象,然后将所创建的对象发布到主题.
此时将调用该主题的任何订阅者,所发布的对象在该ibm.
com/developerWorks/cn/developerWorks使用Dojo和WebSpherePortal实现客户端InterportletCommunication第3页,共10调用中以参数的形式进行传递,从而使订阅者对新数据做出反应;例如,订阅者可执行异步调用并(或)更新其显示.
可以完整地将此设计映射到Portlet之间的客户端通信.
由于Portlet应使用标记将其DOM元素和JavaScript元素区别开来,因此,一个Portlet要从另一个Portlet的HTML页面中侦听DOM事件,就会非常困难.
要解决此难题,您可以使用Dojo事件主题,这样,您就可以使多个Portlet对一个Portlet中的DOM事件做出响应,在此期间,这些Portlet仍能保持其各自的独立性.
例如,动态Portlet可以执行异步调用以检索信息,然后使用事件主题向其他Portlet提供已更新的信息.
dojo.
event.
topicAPI的总结下文将概述Dojo主题API,并描述如何使用各种方法以便在JavaScript组件之间进行通信.
dojo.
event.
topic.
registerPublisher(Stringtopic,Objectobj,StringfuncName)将函数注册为主题的发布者.
在随后调用该函数时,就会将事件发布到该主题,函数的参数会传递到任何已在该主题上注册的侦听器.
dojo.
event.
topic.
publish(Stringtopic,Objectmessage)将所传递的对象手动发布到特定主题.
然后,该对象将被传递到任何已在该主题上注册的侦听器.
dojo.
event.
topic.
subscribe(Stringtopic,Objectobj,StringfuncName)订阅特定主题的函数.
在随后将事件发布到该主题时,将会创建一个针对已订阅函数的函数调用.
侦听器在任何时候都可以订阅主题,即使在发布者未引用该主题的情况下也可以对其进行订阅.
Dojo在订阅者或发布者首次引用主题之时创建该主题.
dojo.
event.
topic.
unsubscribe(Stringtopic,Objectobj,StringfuncName)取消订阅特定主题的函数.
dojo.
event.
topic.
destroy(Stringtopic)销毁该主题,并注销该主题的所有侦听器.
当您引用发布者或订阅者时,主题API将指定对象及函数名称.
使用此方法的目的是为了使用Dojo小部件系统,以便可以注册特定的小部件实例.
如果您不打算使用小部件,则可以选择将主题订阅者实现为JavaScript对象或实现为简单的函数.
在示例应用程序中,主题订阅者被实现为JavaScript对象.
如果您更喜欢使用简单的JavaScript函数,将对象指定为window就可以使用简单的JavaScript函数.
例如:dojo.
event.
topic.
subscribe("/myApp/myTopic",window,"myHandler");此代码将会对"/myApp/myTopic"主题进行订阅.
当将事件发布到该主题时,将会调用JavaScript函数myHandler,所发布的事件在该调用中以参数的形式进行传递.
工作示例让我们探讨一个简单的配置,该配置包括一个事件发布者Portlet、两个侦听器Portlet和单个主题.
所发布的事件对象将包含可供侦听器Portlet使用的两个数据字段.
在Portlet之间进行通信的事件的序列如下所示:developerWorksibm.
com/developerWorks/cn/使用Dojo和WebSpherePortal实现客户端InterportletCommunication第4页,共10图1示例Portlet事件流1.
用户在发布者Portlet上单击PublishEvent按钮.
此操作将创建DOM事件,该事件可触发JavaScript处理程序函数.
2.
该处理程序使用Dojo库创建一个独立的事件对象,然后将该事件发布到主题.
该主题的任何订阅者可接收这一新事件,而无需连接到原始的PublishEvent按钮.
3.
侦听器Portlet包含由Dojo调用的主题订阅函数及用于接收事件对象的主题订阅函数.
这些函数使用事件中包含的信息对Portlet显示进行更新.
在示例中,发布者Portlet会记录PublishEvent按钮被点击的次数.
所发布的事件包含该计数及一条文本消息.
每个侦听器Portlet将使用该事件消息中的一个元素更新其显示.
侦听器Portlet在每次处理事件时,更新的区域将会发出闪光,以引起用户注意更改的地方.
此闪光效果并不是事件发布/订阅过程中的一部分;添加此效果的目的是为了提高演示效果.
事件发布者Portlet需要在事件发布者Portlet中创建一个按钮,用户可单击该按钮对事件进行发布,并且需要在其中创建一个计数器以记录按钮的被点击次数.
清单1显示了相关的HTML/JavaScript源代码,可使用这些源代码创建该按钮,添加处理程序函数以处理按钮点击事件,使计数器上的数字可以根据点击事件进行递增,并最终发布我们的事件.
清单1.
事件发布者Portlet的源代码ThebuttonbelowwillpublishaDojoeventtoallregisteredsubscribers.
_publishButton">PublishEvent//LoadDojo'scoderelatingtowidgetmanagingfunctionsdojo.
require("dojo.
widget.
*");//LoadDojo'scoderelatingtotheButtonwidgetdojo.
require("dojo.
widget.
Button");//LoadDojo'seventhandlingfunctionalitydojo.
require("dojo.
event.
*");dojo.
require("dojo.
event.
topic.
*");//Registerourinitfunctiondojo.
addOnLoad(_init);//Clickcounteribm.
com/developerWorks/cn/developerWorks使用Dojo和WebSpherePortal实现客户端InterportletCommunication第5页,共10var_counter=0;//Initfunctionforthisportlet'sDojocomponentsfunction_init(){varpubButton=dojo.
widget.
byId("_publishButton");dojo.
event.
connect(pubButton,'onClick','_onButton');}//ButtononClickhandlerfunction_onButton(){_counter++;varevt={count:_counter,message:"Clickmessage#"+_counter};dojo.
event.
topic.
publish("/myApp/myTopic",evt);}阅读完上述代码后,您将了解到dojoType标记将PublishEvent按钮标识为DojoButton小部件.
在JavaScript部分中,dojo.
require语句将标识该部件所使用的Dojo库.
调用dojo.
addOnLoad()时,会将init函数添加到函数列表中,页面DOM完成加载后,Dojo将会调用此列函数.
此技术与在window.
onLoad处理程序中设置函数类似,唯一的不同之处在于:Dojo处理多个init函数,这些函数都需要在文档完成加载之后运行.
该功能在Portal应用程序中非常有用,因为该功能允许每个Portlet都指定一个JavaScriptinit函数,而不用担心window.
onLoad处理程序会被覆盖.
使用标记(来自标准Portlet标记库)对该Portlet中的JavaScript函数和变量设置了命名空间.
该标记将被字母-数字字符串替代,该字符串是Portlet实例特有的,这可以防止在一个页面上组装多个Portlet时出现命名空间冲突问题.
init函数通过PublishEvent按钮的widgetId对其进行定位,然后将该小部件的onclick事件连接到事件处理程序.
事件处理程序将递增计数器,构造事件对象,并使用dojo.
event.
topic.
publishAPI将该事件对象发布到名为myApp/myTopic的主题.
事件对象具有以下两个元素:count,计数器的值message,文本消息(包含计数器)Dojo将事件对象传递到每个事件订阅者,然后,这些事件订阅者就可以对合适的内容进行处理.
事件订阅者Portlet需要在事件订阅者Portlet上创建一个显示字段,接收到所发布的事件时,将使用该事件的信息对该显示字段进行更新.
订阅者Portlet还需要在主题上注册其事件处理函数.
最方便的做法是,在init函数中执行该注册操作,该函数与事件发布者中使用的函数类似.
清单2中显示了事件订阅者Portlet的HTML/JavaScript源代码.
清单2.
事件订阅者Portlet源代码ButtonClickCount_count"style="font-size:x-large;">0//LoadDojo'seventhandlingfunctionalitydojo.
require("dojo.
event.
*");dojo.
require("dojo.
event.
topic.
*");developerWorksibm.
com/developerWorks/cn/使用Dojo和WebSpherePortal实现客户端InterportletCommunication第6页,共10dojo.
require("dojo.
lfx.
html");dojo.
require("dojo.
gfx.
color");dojo.
addOnLoad(_init);//Initfunctionforthisportlet'sDojocomponentsfunction_init(){_myListener=new_listener();_myListener.
load();}//eventlistenerobjectfunction_listener(){//Eventhandler-overrideforeachportletthis.
handleEvent=function(args){varcountElement=document.
getElementById("_count");countElement.
innerHTML=args.
count;dojo.
lfx.
html.
highlight("_count",dojo.
gfx.
color.
named.
blue,500).
play();}this.
load=function(){dojo.
event.
topic.
subscribe("/myApp/myTopic",this,this.
handleEvent);}}类似于事件发布者Portlet,dojo.
require语句将指定该部件所需要的Dojo库,而dojo.
addOnLoad将对Portlet的init函数进行注册.
init函数将创建一个新的事件侦听器对象,然后通过调用其加载方法向名为/myApp/myTopic的主题订阅该对象.
当事件被发布到该主题时,将会调用侦听器对象的handleEvent方法.
事件处理程序在显示消息计数的位置查找DOM元素,然后使用事件对象中传递的新值对该元素的HTML进行更新.
然后,处理程序将调用dojo.
lfx.
html.
highlight(),以实现可视化突出显示效果,从而使用户注意到已更新的区域.
事件应用程序包括另一个具有相同功能的事件订阅者Portlet;该Portlet将显示事件消息,而不显示计数.
两个侦听器从事件发布中接收同一对象,但在该对象中选择处理不同的成员.
随着自媒体和短视频的发展,确实对于传统的PC独立网站影响比较大的。我们可以看到云服务器商家的各种促销折扣活动,我们也看到传统域名商的轮番新注册和转入的促销,到现在这个状态已经不能说这些商家的为用户考虑,而是在不断的抢夺同行的客户。我们看到Namecheap商家新注册域名和转入活动一个接一个。如果我们有需要新注册.COM域名的,只需要5.98美元。优惠码:NEWCOM598。同时有赠送2个月免费域名...
标题【萤光云双十二 全场6折 15元/月 续费同价】今天站长给大家推荐一家国内云厂商的双十二活动。萤光云总部位于福建福州,其成立于2002 年。主打高防云服务器产品,主要提供福州、北京、上海 BGP 和香港 CN2 节点。萤光云的高防云服务器自带 50G 防御,适合高防建站、游戏高防等业务。这家厂商本次双十二算是性价比很高了。全线产品6折,上海 BGP 云服务器折扣更大 5.5 折(测试了一下是金...
ucloud云服务器怎么样?ucloud为了扩大云服务器市场份额,给出了超低价云服务器的促销活动,活动仍然是此前的Ucloud全球大促活动页面。目前,ucloud国内云服务器2元/月起;香港云服务器4元/首月;台湾云服务器3元/首月。相当于2-4元就可以试用国内、中国香港、中国台湾这三个地域的云服务器1个月了。ucloud全球大促仅限新用户,国内云服务器个人用户低至56元/年起,香港云服务器也仅8...