引言: 读此篇文章时,假设您已经具备了JavaServer Faces Technology的基础知识.
本文从Dynamic Faces所提供的一个例子出发.
Backing Bean
FruitInfoBean .java
package simpleDynamicFaces;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
public class FruitInfoBean {
/** Creates a new instance of FruitInfoBean */
private Map<Object, Object> fruitNamesMap = new HashMap<Object, Object>();
private String fruit = null;
private String variety = null;
private String varietyInfo = null;
public FruitInfoBean() {
this.init();
}
private void init() {
FacesContext context = FacesContext.getCurrentInstance();
System.out.println("Locale:" + context.getViewRoot().getLocale());
fruit = "Pear";
variety = "Aurora";
fruitNamesMap.put("Pear", "Aurora,Bartlet,Bosc,Comice,Delicious");
fruitNamesMap.put("Apple", "Adanac,Akane,Ballarat,Braeburn,Fuji,Gala");
fruitNamesMap.put("Orange", "Berna,Hamlin,Moro,Navel,Valencia");
fruitNamesMap.put("Peach",
"Brighton,Clingstone,Contender,Eden,Freestone");
}
/*
* Handler method called when user selects a variety from the menu. This
* method updates the variety component model value and sets the varietyInfo
* model value to the appropriate message.
*/
public String updateVariety(ValueChangeEvent e) {
String newVariety = (String) e.getNewValue();
String currentFruit = getFruit();
setVarietyInfo("Information updated:" + newVariety + " Old:"
+ currentFruit);
return null;
}
public String getFruit() {
return this.fruit;
}
public void setFruit(String fruit) {
this.fruit = fruit;
}
protected ArrayList<SelectItem> fruits = null;
public ArrayList<SelectItem> getFruits() {
fruits = new ArrayList<SelectItem>();
fruits.add(new SelectItem("Pear", "Pear"));
fruits.add(new SelectItem("Apple", "Apple"));
fruits.add(new SelectItem("Orange", "Orange"));
fruits.add(new SelectItem("Peach", "Peach"));
return fruits;
}
public String getVariety() {
return this.variety;
}
public void setVariety(String variety) {
this.variety = variety;
}
protected ArrayList<SelectItem> varieties = null;
public ArrayList<SelectItem> getVarieties() {
varieties = new ArrayList<SelectItem>();
String[] fruitVarieties = fruitNamesMap.get(this.fruit).toString()
.split(",");
for (int i = 0; i < fruitVarieties.length; i++) {
varieties.add(new SelectItem(fruitVarieties[i], fruitVarieties[i]));
}
return varieties;
}
/*
* Handler method for the event of selecting a fruit. This method sets the
* model value for the variety component and sets the varietyInfo model
* value to the appropriate message.
*/
public void changeFruit(ValueChangeEvent e) {
String fruitValue = (String) e.getNewValue();
String[] varieties = fruitNamesMap.get(fruitValue).toString()
.split(",");
setVarietyInfo("Information:" + (varieties[0]));
setVariety(varieties[0]);
}
public String getVarietyInfo() {
return this.varietyInfo;
}
public void setVarietyInfo(String varietyInfo) {
this.varietyInfo = varietyInfo;
}
/*
* The following code is used with the installDeferredAjaxTransaction use
* case
*/
private String fruitQuiz = null;
public String getFruitQuiz() {
return this.fruitQuiz;
}
public void setFruitQuiz(String fruit) {
this.fruitQuiz = fruit;
}
}
fireAjaxTx.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces"%>
<f:view>
<html>
<head>
<title>Fruit Varieties</title>
<jsfExt:scripts />
</head>
<body bgcolor="white">
<h:form prependId="false" id="form">
<h1>Fruit Varieties</h1>
<h:panelGrid columns="2" cellpadding="4">
<h:outputText value="Select a fruit:" />
<h:outputText value="Select a variety:" />
<h:selectOneRadio id="fruit" value="#{fruitInfoBean.fruit}"
onclick="DynaFaces.fireAjaxTransaction(this, { execute: 'fruit'});"
valueChangeListener="#{fruitInfoBean.changeFruit}">
<f:selectItems value="#{fruitInfoBean.fruits}" />
</h:selectOneRadio>
<h:selectOneMenu id="variety" value="#{fruitInfoBean.variety}"
onchange="DynaFaces.fireAjaxTransaction(this, { execute: 'variety' });"
valueChangeListener="#{fruitInfoBean.updateVariety}">
<f:selectItems value="#{fruitInfoBean.varieties}" />
</h:selectOneMenu>
</h:panelGrid>
<h:outputText id="varietyInfo" value="#{fruitInfoBean.varietyInfo}" />
</h:form>
</body>
</html>
</f:view>
其中的
DynaFaces.fireAjaxTransaction
方法由jsf-extensions-dynamic-faces.jar里的com_sun
_
faces_ajax.js定义,这个方法可以在JSF组件级别上执行AJAX异步更新.
使用fireAjaxTransaction:
1.在JSF组件的标签里加JavaScript 事件属性,如:onClick="DynaFaces.fireAjaxTransaction(paras)"
2. 在DynaFaces.fireAjaxTransaction加上paras,以便可以传递一些参数到Server.
execute: 'fruit'的意思是:Id为
fruit的JSF组件(包括这个组件的所有Children),将
会
Go Through JSF Life Circle的
execute
部分.
在这部分生命周期后,当前页面所有
的
JSF组件将会通过
Ajax
被
re-render(
这里是默认行为,
因为没有指定render属性
),
其中execute生命周期部分所做的工作如下:转换和验证数据,更新数据模型和处理Action事件.
value-change
事件属于
fruit
组件,所以当发出
AJAX
请求时,该事件也会被处理,从而达到更新模型数据的目的.
常用的属性:
1. execute: A JavaScript String specifying which JSF component id's to process.
2. immediate: Not really needed, but if there was validation on the field in "execute" immediate would skip the validation.
3. inputs: The values sent to the server. This may be different than the components processed.
4. render: This specifies which area(s) of the screen should be updated with the response. In this case the <div> around our message text.
所需的Lib如下:
有关Dynamic Faces的包可以从这里下载:
https://jsf-extensions.dev.java.net/servlets/ProjectDocumentList