论坛首页 Java版 Webwork

WebWork2.2新特性(九) AJAX

浏览 8444 次
该帖已经被评为精华帖
作者 正文
时间:2005-09-14
WebWork2.2新特性(九) AJAX之介绍

在WebWork2.2中,引入了Dojo ( http://dojotoolkit.org ) 和DWR ( http://getahead.ltd.uk/dwr/ ) 两个新的类库来支持AJAX功能.

其中主要增加的特性包括:
1.Remote Div Tag -- 远程区域块标签,通过异步调用获取内容,来动态更新Div.可以循环更新.
2.Remote A Tag --远程链接标签,点击链接时进行一个远程异步调用,可以动态更新Div的内容.
3.Tabbed Panelds --选项卡页面,和普通程序中的选项卡一样,可以有多个选项页面,每个页面的内容都可以设置(本地或者从远程获取),点击一个选项页,切换页面.
4.Remote Form --远程表单,也就是提交但不刷新的表单,点击提交按钮,页面不刷新,通过远程异步调用,更新目标区域的内容.
5.Form Validation --表单校验,在表单中的每个控件输入数据都可以进行即时的校验,主要使用的是DWR.这个在前面已经演示过了.


目前这几个控件在IE上表现的都有问题:
目前Remote Form在IE下不工作,在FireFox下正常工作.
目前动态刷新在IE上好像都有缓存问题,在FireFox下没有问题.(如果在结果页面增加清除缓存的代码,可以解决这个问题)


因为以前没有使用过AJAX,所以后面的文字基本是把webwork wiki上的文档翻译一下,然后按照webwork自带的ajax的教程讲解一下.

建议使用这几个标签之前,可以先了解一下Dojo的工作原理,这样才能知其所以然.

清除缓存的代码:
[code:1]
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
[/code:1]

或者用html的meta来试试,不过那就包含在内容里了.


为了使用WebWork的AJAX组件,我们需要在页面里面根据Dojo的做法包含一些代码,例如ajax例子里面的commonInclude.jsp文件:

[code:1]
<%@ taglib prefix="ww" uri="/webwork" %>
<!--// START SNIPPET: common-include-->
<script language="JavaScript" type="text/javascript">
// Dojo configuration
djConfig = {
baseRelativePath: "<ww:url includeParams="none" value="/webwork/dojo/"/>",
isDebug: false
};
</script>

<script language="JavaScript" type="text/javascript"
src="<ww:url includeParams="none" value="/webwork/dojo/dojo.js" />"></script>
<script language="JavaScript" type="text/javascript"
src="<ww:url includeParams="none" value="/webwork/CommonFunctions.js" />"></script>

<script language="JavaScript" type="text/javascript">
dojo.require("dojo.io.BrowserIO");
dojo.require("dojo.event.topic");
dojo.require("webwork.widgets.Bind");
dojo.require("webwork.widgets.BindDiv");
dojo.require("webwork.widgets.BindButton");
dojo.require("webwork.widgets.BindAnchor");
</script>
<!--// END SNIPPET: common-include-->
[/code:1]

这个文件里面对Dojo进行了设置,包含dojo.js,并且引入了webwork实现的这几个装饰件的代码,在后面的每个例子中,都要包含这个文件,因为后面的介绍中将省略这个文件的介绍,要想了解更多信息,可以参考Dojo的文档.
   
时间:2005-09-14
WebWork 2.2新特性(九) AJAX之Remote Div Tag

首先是wiki上的文档翻译:


Remote DIV 标签和普通的Html的DIV标签工作方式是一样的,但是它可以通过标签内指定的一个网址来装载它的内容.

属性

名称 描述

[list]id (必有): DIV的ID [/list:u]
[list]href (必有): 用来获取内容的网址 [/list:u]
[list]delay: 第一次装载内容需要延迟多长时间 (毫秒) [/list:u]
[list]updateFreq: 多长时间重新取一次内容 (毫秒)[/list:u]
[list]loadingText: 装载内容中对用户显示的文字 (特别是取内容的时候要花费很长的时间 [/list:u]
[list]errorText: 如果取内容时发生了错误,向用户显示的提示[/list:u]
[list]showErrorTransportText: true/false - 当获取内容有问题的时候,是否把错误信息当作内容显示[/list:u]
[list]listenTopics: 监听的Topic名称(多个逗号分割), 将会导致此DIV重新获取内容[/list:u]
[list]afterLoading: 获取内容后要执行的Javascript代码[/list:u]


其他功能
使用javascript代码我们还可以刷新内容,停止或者开始刷新组件.例如一个id是"remotediv1"的div组件:

开始刷新的javascript代码:
[code:1]
remotediv1.start();
[/code:1]
停止刷新的javascript代码:
[code:1]
remotediv1.stop();
[/code:1]
刷新内容的javascript代码:
[code:1]
remotediv1.bind();
[/code:1]


Remote DIV标签我觉得最值得关注的特性:
[list] 可以自己重新装载自己的内容[/list:u]
[list]可以监听Topic,也就是别的动作可以引发更新内容的行为[/list:u]
[list]JavaScript代码可以控制它的行为[/list:u]


首先我们来看Remote Div标签的最简单的一个例子example1.jsp:
[code:1]

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="ww" uri="/webwork" %>
<html>
<head>
<title>Ajax Examples</title>
<jsp:include page="../commonInclude.jsp"/>
</head>
<body>
<ww:div id="once" theme="ajax" cssStyle="border: 1px solid yellow;"
href="/AjaxTest.action" delay="5000" loadingText="loading...">Initial Content</ww:div>
</body></html>

[/code:1]
注:了解commonInclude.jsp,请阅读"AJAX之介绍".


我们再来看example1.jsp这个文件,内容非常简单,使用了一个ww:div标签,设置了一个id,使用的是ajax这个模板(如果你想定义自己的模板,请务必参考ajax模板的编写方法),设置读取内容的url为"/AjaxTest.action",设置延迟5000毫秒后读取内容,装载内容时显示的文本设置为"loading...",div显示时的初始内容时"Initial Content".

是的,很简单,在打开网页5秒后,标签会自动去访问"/AjaxTest.action",并把获取的内容设置为Div的内容.


我们再来看一个定时自动刷新的例子:
[code:1]

<ww:div id="twoseconds" cssStyle="border: 1px solid yellow;" href="/AjaxTest.action"
theme="ajax" delay="2000" updateFreq="3000" errorText="There was an error">Initial Content</ww:div>

[/code:1]

这个标签产生的结果每3秒钟刷新一次DIV的内容,和上面的差不多,只是多了一个updateFreq设置.

此标签还有一个afterLoading属性,使用方法如下:
[code:1]
<ww:div ...... afterLoading='alert("done")'>Initial Content</ww:div>[/code:1]

或者
[code:1]
<ww:div ...... afterLoading="alert(\"done\")">Initial Content</ww:div>
[/code:1]

注意:目前使用afterLoading="alert('done')"的方法好像有点问题,好像是dojo内部处理引发的问题.


监听Topic是通过JavaScript代码或者其他部件来触发的,使用JavaScript的示例如下:
[code:1]
<ww:div
id="once" theme="ajax" cssStyle="border: 1px solid yellow;" href="/ajax/test1.jspa"
delay="5000" loadingText="loading..." listenTopics="scud1" >Initial Content</ww:div>
[/code:1]

这个Div标签将监听Topic为"scud1"的事件.

我们可以使用一个普通按钮来触发事件:
[code:1]
<script type="text/javascript">
function scud1() { dojo.event.topic.publish( "scud1", "alert('test');" ); }
</script>
<INPUT type="button" onclick="scud1()" value="click">

[/code:1]
点击这个按钮,将会导致Div标签重新装入内容. 注意一个Div标签可以监听多个Topic,用逗号分割即可.

至于使用其他部件触发事件的代码,我们将会在使用Remote A Tag时用到.
   
0 请登录后投票
时间:2005-09-14
WebWork 2.2新特性(九) AJAX之Remote A Tag

首先,我们把wiki上的文档翻译一下:

远程链接标签允许对一个URL进行访问,但可以不刷新页面.

属性

名称 描述
id (required): 元件ID
href (required): 用来获取内容的URL
errorText: 如果取内容时发生了错误,向用户显示的提示
showErrorTransportText: true/false - 当获取内容有问题的时候,是否把错误信息当作内容显示
notifyTopics: 远程调用完成后,对那些Topic进行事件激发,可以多个,用逗号分割
afterLoading: 远程调用完毕后,要执行的Javascript代码





Remote A标签我觉得值得关注的特性是notifyTopics,也就是可以触发别的控件的事件,它可以是一个发令员.


首先我们来看Remote A标签的一个例子
[code:1]

<ww:a id="link1" theme="ajax" href="/AjaxRemoteLink.action"
showErrorTransportText="true" errorText="An Error ocurred">Click Me</ww:a>
[/code:1]
这个标签的含义:
ID为link1
使用ajax模板
点击链接时访问的网址为"/AjaxRemoteLink.action"
如果发生错误把错误当作内容处理
错误信息为"An Error ocurred"

点击这个链接,页面会去访问"/AjaxRemoteLink.action",如果返回的结果是JavaScript,就会执行相应的JavaScript.

如果返回的内容不是JavaScript,系统不会有任何动作,也不会触发事件. (这个确实有点令人迷惑,也许会改进?如何改进哪?)

我们再来看一个可以触发事件的标签,这个是和DIV结合的,可以参考ajax例子中的lesson3中的例子:
[code:1]
<ww:div id="one" cssStyle="border: 1px solid yellow;"
href="/ajax/test1.jspa" theme="ajax"
listenTopics="mylink1_click" delay="1000">Initial Content</ww:div>

<ww:a id="link1" theme="ajax" href="/ajax/urltestjs.jspa"
showErrorTransportText="true"
notifyTopics="mylink1_click"
errorText="An Error ocurred">Update</ww:a>

[/code:1]

首先是一个要被触发的Div标签,它监听的Topic为"mylink1_click"(可以监听多个).然后是一个A标签,触发的Topic是"mylink1_click",此处也可以是多个,但用户点击这个Remote A标签时,A标签会执行返回的JavaScript代码,也会触发Div标签重新装载它自身的内容.

如果标签还有afterLoading='alert("done")'的代码,在触发Div事件之前还会执行这个 afterLoading,可以阅读前面Div标签中关于afterLoading的说明.


这个Remote A的功能就这么多,本来以为应该有一个点击后用指定的内容替换目标Div的内容,不过目前没有发现有直观的做法可以实现这个功能,也许有其他做法更合适吧.


注:撰写本文时,WebWork2.2还没有最后发布,在最后发布的版本里应该会有一些变化,请以最后发布的版本为准.
   
0 请登录后投票
时间:2005-09-14
WebWork2.2新特性(九) AJAX之Tabbed Panels(选项卡)


Tabbed Panels(选项卡)是一个具有多个选项页面的控件.在应用程序中很常见.

在WebWork中,还有另外一个tabbedPane,和这个类似,不过它的使用方法和本控件不同,具体可以参考以前版本中的TabbedPaneTest.action例子.

首先,我们把wiki文档翻译一下:

此面板组件允许你有一个选项卡面板,每个选项页可以拥有本地的内容或者远程的内容(用户每次选择这个选项页都会刷新内容).

属性 - ww:tabbedPanel
名称 描述
id (required): 组件标识

属性 - ww:panel
名称 描述
id (required): 标识ID
tabName (required): 选项文字,显示在选项页列表的头部
href (required if remote panel): 用来获取内容的网址
remote: true/false - 用来确定这是一个远程面板(ajax)还是一个本地面板 (内容会装入可视或隐藏的容器)
loadingText: 新的远程内容被获取之前显示的文字
reloadingText: 装载内容时对用户显示的文字,特别是取内容的时候要花费很长的时间 (仅对远程面板可用)
errorText: 如果取内容时发生了错误,向用户显示的提示 (仅对远程面板可用)
showErrorTransportText: true/false - 当获取内容有问题的时候,是否把错误信息当作内容显示(仅对远程面板可用)
listenTopics: 监听的Topic名称(多个逗号分割),将会导致此面板重新获取内容

额外的配置
如果你在寻找"好看"的圆角效果, 这里有一个可用的配置. 这里假设选项卡的背景色是白色.如果你使用了不同的颜色,请修改 Rounded() 方法的参数.
[code:1]
<link rel="stylesheet" type="text/css" href="<ww:url value="/webwork/tabs.css"/>">
<link rel="stylesheet" type="text/css" href="<ww:url value="/webwork/niftycorners/niftyCorners.css"/>">
<link rel="stylesheet" type="text/css" href="<ww:url value="/webwork/niftycorners/niftyPrint.css"/>" media="print">
<script type="text/javascript" src="<ww:url value="/webwork/niftycorners/nifty.js"/>"></script>
<script type="text/javascript">
dojo.event.connect(window, "onload", function() {
if (!NiftyCheck())
return;
Rounded("li.tab_selected", "top", "white", "transparent", "border #ffffffS");
Rounded("li.tab_unselected", "top", "white", "transparent", "border #ffffffS");
// "white" 要替换为你的背景色
});
</script>
[/code:1]



我们首先来分析一个例子,
[code:1]
<ww:tabbedPanel id="test" theme="ajax">

<ww:panel id="one" tabName="one" theme="ajax">
This is the first pane<br/>
<ww:form>
<ww:textfield name="tt" label="Test Text"/> <br/>
<ww:textfield name="tt2" label="Test Text2"/>
</ww:form>
</ww:panel>

<ww:panel id="two" tabName="two" theme="ajax">
This is the second panel
</ww:panel>

</ww:tabbedPanel>
[/code:1]

这个选项卡包含了2个选项页面,都是本地页面,使用ww:panel来定义页面内容,使用的模板都是ajax模板.

我们再来看如何定义远程页面:
[code:1]
<ww:tabbedPanel id="test2" theme="simple" >
<ww:panel id="left" tabName="left" theme="ajax">
This is the left pane<br/>
<ww:form >
<ww:textfield name="tt" label="Test Text" /> <br/>
<ww:textfield name="tt2" label="Test Text2" />
</ww:form>
</ww:panel>
<ww:panel remote="true" href="/AjaxTest.action" id="ryh1" theme="ajax" tabName="remote one" />
<ww:panel id="middle" tabName="middle" theme="ajax">
middle tab<br/>
<ww:form >
<ww:textfield name="tt" label="Test Text44" /> <br/>
<ww:textfield name="tt2" label="Test Text442" />
</ww:form>
</ww:panel>
<ww:panel remote="true" href="/AjaxTest.action" id="ryh21" theme="ajax" tabName="remote right" />
</ww:tabbedPanel>

[/code:1]
可以看到定义了四个选项页面,其中有2个是远程页面.

每次切换页面时,相应"远程页面"的内容都会刷新,本地页面是不刷新的.

同时远程页面也可以监听Topic,具体使用可以参考Remote A或者使用JavaScript进行调用.(注:beta1里面的相关程序有一些错误)
   
0 请登录后投票
时间:2005-09-14
WebWork 2.2新特性(九) AJAX之Remote Form

Remote Form(远程表单)最大的特点就是可以不用刷新页面而进行提交.

wiki翻译如下:

远程表单允许提交表单但是不刷新页面. 表单提交的结果可以设置为任何页面上的元素的内容.

属性
为了让表单具有ajax功能, 必须使用ww:form, 指定模板主题为 "ajax". 另外, 必须配合 ww:submit 才能一起工作. ww:submit组件相关的AJAX属性包括:

名称 描述
resultDivId : 要存放结果的Html元素的id (可以是表单的id或者页面上的任何id)
notifyTopics : 表单提交后,对哪些Topic进行事件激发,可以多个,用逗号分割
afterLoading: 表单提交后要执行的Javascript代码



Remote Form是由Form和Submit标签协作运行的,它有三个特性:
1.可以用提交后获取的内容替换某个id元素的内容
2.提交后可以触发事件
3.提交后可以执行一段JavaScript

我们来看第一个例子:
[code:1]
<div id='two' style="border: 1px solid yellow;"><b>initial content</b></div>
<ww:form id='theForm2' cssStyle="border: 1px solid green;"
action='/AjaxRemoteForm.action' method='post' theme="ajax">
<input type='text' name='data' value='WebWork User'>
<ww:submit value="GO2" theme="ajax" resultDivId="two" />
</ww:form>

[/code:1]

可以看到,form必须使用ajax模板,submit标签也是使用ajax模板(或者具有ajax模板功能的自定义模板),只有使用ajax模板,才具有提交不刷新页面的效果,否则就是普通的表单提交了.
form没有特殊的属性,主要是submit的属性resultDivId,指定目标id为"two",这个id可以是页面上的任何一个元素的id,当然也可以是表单本身.点击提交按钮后,id为"two"的元素的内容被替换为表单提交的结果内容.

另外,submit还有另外2个属性,其中之一是onLoadJS,如果在submit的属性中指定onLoadJS,例如

[code:1]
<ww:submit value="GO4" theme="ajax" onLoadJS="alert('form submitted');"/>
[/code:1]
则表单提交后会执行相应的JavaScript代码.

另外一个属性是notifyTopics,可以触发Topic为指定属性的事件,例如

[code:1]
<ww:div id="once" theme="ajax" cssStyle="border: 1px solid yellow;"
href="/AjaxTest.action" delay="1000"
listenTopics="scud1" loadingText="loading...">Initial Content</ww:div>
<br><br>
<ww:form id='theForm2' cssStyle="border: 1px solid green;"
action='/AjaxRemoteForm.action' method='post' theme="ajax">
<input type='text' name='data' value='WebWork User'>
<ww:submit value="GO2" theme="ajax" notifyTopics="scud1" />
</ww:form>

[/code:1]

提交表单将会触发监听Topic为"scud1"的控件的事件,它们会重载自身的内容.可以参考前面Div 标签的说明.
   
0 请登录后投票
时间:2005-09-14
ajax部分贴完了. 期待webwork提供更多的ajax特性,当然我们也可以自己做.
   
0 请登录后投票
时间:2005-10-23
动作好快呀,俺才刚刚开始。
鄙视自己一下。
   
0 请登录后投票
时间:2007-07-30
是不是 remote div 会受到 sitemesh 的影响啊。我把web.xml的sitemesh过滤器删掉,div的远程内容显示,否则显示errorText。。。
两者怎么共存啊。
   
0 请登录后投票
时间:2007-07-30
是不是 remote div 会受到 sitemesh 的影响啊。我把web.xml的sitemesh过滤器删掉,div的远程内容显示,否则显示errorText。。。
两者怎么共存啊。
   
0 请登录后投票
论坛首页 Java版 Webwork

跳转论坛:
JavaEye推荐