jsf标签<p:ajax>_JSF和Ajax:使用Rational Application Developer V7简化了Web 2.0应用程序

jsf标签<p:ajax>

Ajax的优缺点

尽管不是真正的新事物,也不是革命性的,但Ajax技术在过去一两年中已变得非常流行。 许多主要的网站(例如Google,Yahoo!,Amazon和Netflix)都使用它来改善用户体验。 实际上,改善用户体验是Ajax的全部宗旨。

在过去十年中开发的常规Web应用程序中,用户与浏览器之间以及浏览器与服务器之间的交互是定义明确的且可见的:用户在浏览器中看到一个页面,然后采取行动(从上下文下拉菜单中选择内容,或选中一些复选框),然后通过单击链接或“提交”按钮指示浏览器与服务器进行通信。 浏览器将请求发送到服务器,并在该请求中传递用户的输入。 服务器处理该请求并发送回响应,该响应可以是新页面或相同页面,但是已更新。

这种Web应用程序现在通常称为Web 1.0。 从用户体验的角度来看,它们有两个明显的弱点:

  • 浏览器和服务器之间的交互是由页面上有限数量的控件(通常仅由链接和按钮)启动的。 在用户选择页面上的复选框或在组合框中标记选择之后,很少会立即通知服务器。
  • 浏览器和服务器之间的交互导致更新整个浏览器窗口。 这通常太慢了,以至于用户不得不等待大量时间才能更新页面。 更糟糕的是,当同一页面被重新加载或刷新时,它通常在浏览器窗口中闪烁。

新一代的Web应用程序(通常称为Web 2.0)通过使用Ajax技术(对于异步JavaScript和XML也为AJAX)来解决这些薄弱环节。 在Ajax中,浏览器和服务器之间的交互是在后台发生的,用户并未注意到。 它们也比通常的浏览器-服务器交互更具针对性,因为只能将页面的一部分发送给服务器,并且服务器只能返回页面的一部分进行更新。 作为这种方法的结果,几乎可以通过任何事件来启动浏览器与服务器之间的通信,例如组合框或复选框中的选择更改或鼠标指针悬停。 这带来了明显的好处:

  • 通信速度更快,因为传输的数据更少。
  • 用户停留在同一页面上,因为需要更少的页面导航。
  • 重新加载的页面不会闪烁,因为每个Ajax请求只会更新页面的较小区域。

Ajax背后的想法非常简单:在浏览器中监听事件,向服务器发送后台请求,并在服务器响应时更新页面的一部分。 但是实现可能非常复杂。 它需要对JavaScript™,客户端-服务器通信协议和服务器端代码有深入的了解。 主要浏览器版本之间的差异使开发和调试变得更加棘手。 但是,IBM®Rational®Application Developer版本7发行版提供了开发支持Ajax的Web应用程序所需的一切, 而无需实现所有低级细节。

Rational Application Developer V7提供:

  • JSF扩展,允许在JavaServer™Framework(JSF)中处理Ajax请求
  • 一个JavaScript™库,可以在主要浏览器的所有最新版本中启动Ajax请求,并通过仅更新页面的一部分来处理服务器响应

Rational Application Developer V7中Ajax和JSF实现的技术细节不在本文讨论范围之内,但是让我们研究一下如何一起使用这两种技术。

如何将Ajax与JSF组件一起使用

将Ajax添加到JSF页面需要四个步骤:

  1. 确定将由Ajax请求更新的页面区域。 在Rational Application Developer V7中,您可以将Ajax与几乎所有面板组件的内容一起使用。 面板的范围从简单的容器(例如<h:panelGroup><h:panelGrid> )到功能丰富的面板(例如菜单( <hx:panelMenu> )和对话框( <hx:panelDialog> )。
  2. 选择要使用的Ajax请求的类型。 Rational Application Developer V7 JSF库中支持三种不同类型的Ajax请求:
    • 相同页面的GET请求( <hx:ajaxRefreshRequest>
    • 相同页面的POST请求( <hx:ajaxSubmitRequest>
    • GET请求另一个页面( <hx:ajaxExternalRequest>
  3. 配置参数以通过Ajax请求传递到服务器。
    • 对于GET请求,您可以在页面上传递各种输入字段的值。
    • 对于POST请求,将提交整个表单。
  4. 确定启动Ajax请求的事件。 这可以是任何客户端JavaScript事件,例如,按钮的onclick ,输入字段的onblur或复选框的onchange

让我们使用“ Hello,world”类型的应用程序的简单示例逐步完成所有这些步骤。 您将构建一个包含两个字段的页面:输入和输出。 用户在输入字段中跳出之后,您将使用Ajax将用户输入的值发送到服务器,并用问候语更新输出字段。

设置您的Web项目

首先,创建一个Web项目(请参见图1 ):

  • 从菜单中选择文件 > 新建 > 项目 > 动态Web项目
  • 在“ 新建项目”向导中:
    1. 输入项目名称(例如, HelloWorld )。
    2. 选择Faces Project配置。
    3. 选择将项目添加到EAR
  • 点击完成
图1. New Dynamic Web Project屏幕
图1. New Dynamic Web Project屏幕显示

要创建一个网页(请参见图2 ):

  • 在“ 项目资源管理器”中右键单击项目名称
  • 从上下文菜单中选择“ 新建” >“ 网页”
  • 在“ 新建网页”向导中,输入页面名称(例如hello )。
  • 点击完成
图2.新建网页向导
图2.新建网页向导

将组件添加到页面

现在您有了可以使用的页面,接下来将添加组件。 您将在文本字段中使用inputText组件,用户将在其中键入名称,并使用outputText组件显示问候语。 因为要使用Ajax更新outputText ,所以需要将其放在面板组件中。 您将在此页面上使用panelGroup组件。

要添加组件:

  • 输入组件从面板的“ 增强的Faces组件”抽屉拖到页面上。
  • 将“ 面板组”框组件从面板中拖到“输入”组件下方的页面上。 当提示您输入分组框类型时,选择“ 分组”
  • 输出组件从面板拖到“面板组”框中。

向面板添加Ajax支持

要通过Ajax(在本例中为“输出”字段)使面板的内容可更新,您需要将面板标记为“ Ajaxable”,并配置希望用户请求传递到服务器的参数。 (参见图3。

  1. 选择outputText组件,然后切换到Properties视图。
  2. 在“属性”视图中,选择h:panelGroup标记,该标记位于左侧标记导航器中h:outputText标记的正上方。
  3. 选择h:panelGroup标记的Ajax页面。
  4. 单击允许Ajax更新复选框。
  5. 选择Refresh作为Ajax请求类型。
图3. panelGroup属性
图3. panelGroup属性

此示例使用Refresh请求来说明如何与Ajax请求一起传递参数。 或者,“提交”请求将提交整个表单。 在这种情况下,由于示例页面上的表单仅包含一个输入字段,因此根本不需要为Ajax请求配置参数。

要为Ajax请求配置参数( 图4 ):

  • 选择“ 单击”以在Ajax属性页面上编辑Ajax请求属性 (请参见前面显示的图3 )。
  • hx:ajaxRefreshRequest标签的“ 属性”页面上:
    1. 单击“ 添加参数”以获取要从浏览器发送的参数。
    2. 从组合框中选择Input组件的名称(在本例中为text1 )。
图4. ajaxRefreshRequest属性
图4. ajaxRefreshRequest属性

您已将panelGroup标记配置为由Ajax请求更新,并使用Input字段的值作为请求的参数。 剩下要做的唯一一件事就是使outputText组件使用此参数显示问候语(请参见图5 ):

  • 选择outputText组件。
  • 在“ 值”字段中输入Hello, #{param.text1}
图5. outputText属性
图5. outputText属性

发起Ajax请求

如果回头看使用Ajax所需的四个步骤 ,您将看到您已经完成了前三个步骤。 现在,您只需要确定将触发Ajax请求的事件。 要在用户跳出输入字段时立即更新问候语,您将在inputText组件上使用onblur事件(请参见图6 ):

  • 选择inputText组件。
  • 切换到快速编辑视图。
  • 在快速编辑视图中:
    1. 在左侧的事件列表中选择onblur事件。
    2. 单击使用预定义的行为复选框。
    3. 选择对指定标记操作的“ 调用Ajax”行为
    4. 选择panelGroup的名称(在本例中为group1 )作为目标。
图6.快速编辑视图
图6.快速编辑视图

现在,您可以保存页面并在服务器上运行它。 当浏览器窗口打开时,您将看到一个输入字段及其下方的“ Hello”文本。 用户在该字段中键入任何内容然后跳出后,问候语将使用用户在输入字段中键入的文本进行更新。 (参见图7。

图7.在服务器上运行网页
图7.在服务器上运行网页

如您所见,您能够使用标准JSF组件构建一个简单而功能强大的Ajax页面,并且绝对没有JavaScript代码。

接下来,让我们看一个更复杂的例子。

如何将Ajax添加到现有的JSF应用程序

考虑一下任何现代电子商务Web应用程序的共同部分:购物车。 如果您曾经在网上购买过任何东西,那么您已经看过了。 典型的购物车显示用户浏览网站时添加到其中的产品的列表,输入字段以更新数量的按钮,进行结帐的按钮等。

如果要查看各种购物车,您可能会注意到它们至少有两个共同点:

  • 通常有一个“更新”按钮,可根据用户在输入字段中输入的数量重新计算总计,税金和运输成本。
  • 购物车中的每个项目通常都是一个链接,可将用户带到产品详细信息页面。

这些是我们在本文开头提到的缺点的很好的例子。 仅当用户单击按钮时,购物车才会更新,并且用户必须导航到另一页才能看到商品的详细说明。 使用Ajax技术,可以极大地改善用户的体验,因为可以在更改数量后立即更新总数,并且可以在同一页面(在设计区域或弹出窗口中)显示项目的详细信息。 。

在本文结尾的“资源”部分中,有一个您可以下载项目,项目演示了如何轻松地将Web 1.0购物车转移到Web 2.0应用程序。 现在,我们将引导您完成该示例应用程序,以便您了解其构建方式以及如何对其进行修改以使用Ajax。

注意:从现在开始,所有引用(JavaServer Pages™[JSP™]名称,组件ID等)都指向您可以下载的AjaxSample应用程序。 请将AjaxSample.zip文件保存到您的计算机系统,然后使用Project Interchange格式将其导入Rational Application Developer V7。

购物车:旧方法

此示例中的购物车使用三个Java™bean:Product,CartItem和ShoppingCart。 您可以在Project Explorer的Java Resources类别下的bean包中找到它们。

  • Product包含有关此网站出售的Product信息:ID,名称,描述,图像和价格。
  • CartItem跟踪购物车中每种产品的数量。
  • ShoppingCart保留购物车清单(产品和数量对); 计算总计,税金和运输成本; 并提供一种基于请求参数中传递的ID来帮助用户查找产品的方法。

如图8所示, cart.jsp是购物车页面的相当简单的实现。

图8.购物车
图8.购物车

该页面使用dataTable组件显示购物车中的所有项目。 数量列使用inputText字段让用户更改订购量。 用户完成所需的所有修改后,可以单击“重新计算”按钮以更新总计,税金和运输成本。 产品名称也是一个链接,可将用户带到另一个页面product.jsp,以查看产品详细信息。 产品的ID作为参数传递。 (参见图9。

图9.产品详细信息
图9.产品详细信息

购物车:新方法

在这里, cartajax.jsp是相同的购物车页面,但已使用Ajax进行了重新设计,以改善用户体验。 新的cartajax.jsp( 图10 )与原始的cart.jsp之间存在三个明显的区别:

  • 没有“重新计算”按钮。 一旦用户从输入字段中跳出,总数就会立即更新。
  • 当用户将鼠标指针移到产品名称上方时,将在弹出窗口中显示产品说明。
  • 当用户单击产品链接时,该产品的完整详细信息显示在购物车下方,而无需更新购物车本身。
图10.带有Ajax的购物车
图10.带有Ajax的购物车

让我们看看这种转变是如何发生的。 为了说明目的,此页面使用所有三种Ajax请求。 另外,与本文开头仅使用IDE功能来设置Ajax功能不同,在这里您可以在“源”模式下看到JSF标记。

摆脱重新计算功能

您无需使用“重新计算”按钮,而是使用清单1所示的ajaxSubmitRequest标记将包含总计,税额和运费的面板声明为“ Ajaxable”。

清单1. ajaxSubmitRequest代码
<h:panelGrid id="totals" styleClass="panelGrid" columns="2" style="text-align:right;">
	<h:outputText id="text4" styleClass="outputText" value="Sub-total:"></h:outputText>
	<h:outputText id="textTotalPrice" value="#{cart.totalPrice}" styleClass="outputText">
		<hx:convertNumber type="currency" />
	</h:outputText>
	... other output components ...
</h:panelGrid> 
<hx:ajaxRefreshSubmit id="refreshTotals" target="totals"></hx:ajaxRefreshSubmit>

您在此处使用的是Ajax请求的Submit类型,因此无需传递任何参数,因为将提交整个购物车表单。 这使所有数量输入字段的值可用于服务器端代码。 面板和Ajax标记与ID和target属性相连,在本示例中,这些属性以粗体突出显示( 清单1 )。 一旦用户从输入字段中跳出,总数就会立即更新。 因此,您可以使用inputText组件的onblur事件来发起请求:

清单2.通过Ajax启动Submit请求的代码
<h:inputText id="textQuantity1" value="#{varproducts.quantity}" styleClass="inputText" 
		size="3">
	<hx:behavior event="onblur" behaviorAction="get" targetAction="totals">
	</hx:behavior>
</h:inputText>

hx:behavior标记是将预定义JavaScript功能附加到JSF组件上的客户端事件的一种非常有效的方法。 在这种情况下,您将在inputText组件上使用onblur事件(事件属性)( hx:behaviorh:inputText的子级),并且您想要对totals组件执行get操作。 在这里, Totals是要更新的面板,而get操作的意思是“获取内容”,因此:使用Ajax更新。

注意:选择cartajax.jsp ,然后选择“在服务器运行”以查看这些标签在浏览器中的协同工作。

从表中的任何输入字段中跳出后,附加到onblur事件JavaScript代码就会立即运行。 它在页面上找到Totals组件,验证是否有与其关联的ajaxRefreshSubmit组件,然后通过将表单发送到服务器来发起Ajax POST请求。 服务器响应时,将使用服务器中的新内容更新“总计”面板。

添加弹出说明

下一个示例使用无模型的Dialog组件(这也是Rational Application Developer V7中的新组件)来显示购物车中物品的描述。 因为Dialog是一个面板,所以可以使用Ajax来更新其内容,就像之前更新panelGroup和panelGrid组件一样( 清单3 ):

清单3.使用新的Dialog组件显示产品描述
<hx:panelDialog type="modeless" id="descriptionPopup" styleClass="panelDialog"
		style="background-color: #fff9ca" movable="false"
		align="relative" valign="relative" saveState="false"
		showTitleBar="false">
	<h:outputText id="textDescription1d"
		value="#{cart.selectedProduct.description}"
		styleClass="outputText">
	</h:outputText>
</hx:panelDialog>
<hx:ajaxRefreshRequest id="showPopup" target="descriptionPopup"	
	params="$$AJAXROW$$form1:tableEx1:itemid"></hx:ajaxRefreshRequest>

这与先前的标记非常相似,除了这次您使用的是Refresh类型的Ajax请求。 因此,您需要将一个参数传递给服务器-特别是要查看其说明的购物车商品的ID。 由于项目位于dataTable中,并且JSF仅保留表中每个组件的一个实例,因此必须让服务器端代码知道您要在活动行中使用该组件的值,这意味着该行生成了请求。 为此,将$$AJAXROW$$键放在组件ID之前。

要在用户将鼠标悬停在某个项目上时显示或隐藏对话框,可以使用Link组件的onmouseoveronmouseout事件,如清单4所示:

清单4.当用户将鼠标指针悬停在项目上时显示或隐藏对话框的代码
<h:outputLink id="link1">
	<h:outputText id="textName1" value="#{varproducts.product.name}"
			styleClass="outputText">
	</h:outputText>
	<hx:behavior event="onmouseover" behaviorAction="get;show"
			targetAction="form1:descriptionPopup;form1:descriptionPopup"></hx:behavior>
	<hx:behavior event="onmouseout" behaviorAction="hide"
			targetAction="form1:descriptionPopup"></hx:behavior>
</h:outputLink>

当用户将鼠标指针移到某个项目上时,您希望对话框的内容进行更新( get操作)并希望对话框显示( show操作)。 当鼠标指针不再位于项目上方时,您希望对话框被隐藏( hide动作)。

在同一页面上显示产品详细信息

您要做的最终改进是在购物车的同一页上显示产品详细信息。 您已经具有显示项目详细信息的页面:product.jsp。 因此,如果您不得不经历重新设计它的所有工作并在cartajax.jsp中重新实现相似的标签,那将是可耻的。 幸运的是,您可以在第三个Ajax请求类型的帮助下使用现有的JSP文件:外部请求(请参见清单5 ):

清单5.在同一页面上显示产品详细信息的代码
<h:panelGrid id="product" width="700" style="margin-top: 20px;"
		styleClass="panelGrid">
	<h:outputText id="text8" styleClass="outputText"
		value="Click on a product to see its details here."
		style="color: gray; font-size: 10pt">
	</h:outputText>
</h:panelGrid>
<hx:ajaxExternalRequest id="showDetails" target="product"
		href="product.faces" source="product"
		params="$$AJAXROW$$form1:tableEx1:itemid">
</hx:ajaxExternalRequest>

您可能已经认识到这种模式:面板组件和关联的Ajax标记。 产品panelGrid充当产品详细信息的占位符。 如果用户未选择产品,则仅显示帮助者文本,该文本向用户解释该页面区域的用途。 当用户单击产品时,面板的内容将使用类似于product.jsp文件( href属性)中定义的panelGrid的panelGrid进行更新。

这次,Link组件的onclick事件启动了Ajax请求,如清单6所示:

清单6.使用onclick事件启动Ajax请求的代码
<h:outputLink id="link1">
	<h:outputText id="textName1" value="#{varproducts.product.name}"
		styleClass="outputText">
	</h:outputText>
	<hx:behavior event="onclick" behaviorAction="get;stop"
		targetAction="product">
	</hx:behavior>
</h:outputLink>

行为( stop )中的第二个动作是防止事件在浏览器中冒泡。 在这种情况下,您不希望该链接像常规链接一样工作,而只是启动Ajax请求,然后停止处理该事件。

您需要做的最后一项更改是关于当前所选产品的ID如何传递到服务器。 在购物车的cart.jsp版本中,使用链接导航到另一个页面,您将ID定义为链接参数( 清单7 ):

清单7.定义为原始购物车中参数中的链接的ID
<h:outputLink id="link1" value="product.faces">
	<h:outputText id="textName1" value="#{varproducts.product.name}"
		styleClass="outputText">
	</h:outputText>
	<f:param name="itemid" id="param1" value="#{varproducts.product.id}" />
</h:outputLink>

使用Ajax时,您不再具有真正的链接,并且使用Ajax标记的params属性将组件的值与请求一起传递。 因此,您需要创建一个隐藏的输入字段来保存链接旁边的ID,而不是在链接上使用参数,并将该组件用作Ajax参数(请参见清单8 ):

清单8.创建一个隐藏的ID输入字段以用作Ajax参数
<h:outputLink id="link1">
	<h:outputText id="textName1" value="#{varproducts.product.name}"
		styleClass="outputText">
	</h:outputText>
</h:outputLink>
<h:inputHidden id="itemid" value="#{varproducts.product.id}" />

<hx:ajaxExternalRequest id="showDetails" target="product"
		href="product.faces" source="product"
		params="$$AJAXROW$$form1:tableEx1:itemid">
</hx:ajaxExternalRequest>

进行此更改后,您对购物车的修改就完成了。

使用Rational Application Developer Ajax工具的其他方式

尽管您对本练习所做的更改显示了JSF标记,但仅出于说明目的,您可以在Rational Application Developer中通过拖放,“属性”视图和“快速编辑”视图轻松地重现它们。 这与构建“ Hello,world”应用程序时在本文第一部分中使用的过程完全相同。 因此,如您在这里所看到的,您可以极大地提高应用程序的可用性,但是您不必扔掉已经完成的任何工作。


翻译自: https://www.ibm.com/developerworks/rational/library/06/1205_kats_rad2/index.html

jsf标签<p:ajax>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值