【发布时间】:2012-11-22 00:29:28
【问题描述】:
场景:我想通过使用 commandLink 使用 AJAX 在 JSF 中部分执行和呈现表单的一部分。由于这将通过 AJAX 完成,据我了解,ViewScoped 应该在 AJAX 请求之间保存页面中组件的值。
我在下面创建了一个示例,其中我有一个输入框,其中输入了订单名称,按下 commandLink(标记为“输入订单”),来自 inputText 的订单名称被添加到名为“订单”的 ArrayList 中,并且“订单”显示在 CommandLink 下方的 DataTable 中。
来自 CommandLink 的 AJAX 请求执行将字符串值添加到“orderName”变量的 inputBox。 AJAX 请求向 processDataTable() 方法发送一个 ActionEvent,该方法获取“orderName”值并将其添加到“orders”列表中。然后“orderName”为空。然后,AJAX 请求会呈现带有为空的“orderName”的 inputText 组件,以及显示所有先前输入的订单的 DataTable,包括来自该请求的新添加的“orderName”。
问题:如果我使用的是 SessionScoped bean,则代码有效,但如果我使用 ViewScoped bean,则代码无效。我在代码中添加了 System.out.println() 以查看发生了什么。如果我使 bean SessionScoped,那么一切都按计划进行。 inputText 值是通过 set 方法设置的,processOrder() 方法将“orderName”String 添加到“orders”List 中,重新渲染DataTable 以显示这个添加的名称。 ...
对于 ViewScoped bean,“orderName”值设置为 InputText 组件的值,但在 ProcessOrder() 方法中为“null”,将“null”添加到“orders”列表和 DataTable除了 null 之外没有什么可显示的。
如果我在添加“orderName”之前使用 orders.add("Some Name") 在 processOrder() 中手动添加 orderName,则“orders”将保留 {"Some Order", "null"} 和更改到 Orders 仍然没有使用 AJAX 重新渲染。
所有都适用于 SessionScoped bean 而不是 ViewScoped bean?我还尝试了使用 CommandLink 而不是 ActionListener 的 Action 属性,同样的故事.. 适用于 SessionScoped 但不适用于 ViewScoped。
我在这里只能想到两件事,1)我错过了 AJAX 和 CommandLink 如何协同工作的关键点,以及 ViewScoped 应该如何工作(很有可能);或 2) 出于某种原因,我如何使用 CommandLink 提交 AJAX 调用,每次单击它都会刷新页面,从而删除“订单”列表的先前值。但是,这仍然不能解释为什么如果我手动将订单输入到列表中,它仍然不会在 AJAX 请求中使用 ViewScoped bean 呈现,而是会使用 SessionScoped bean。
请帮忙!!??
这是我的代码:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
@Named(value = "testBean")
@ViewScoped
public class DataTableTest implements Serializable {
private String orderName;
private List<String> orders = new ArrayList<String>();
public DataTableTest () {}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
System.out.println(orderName + " in setOrderName");
}
public List<String> getOrders() {
return orders;
}
public String processDataTable(ActionEvent event) {
System.out.println(orderName + " before getting added to orders list in processDataTable");
orders.add(orderName); // adds the orderName to the orders list, so it can be viewed in the DataTable
orderName = null; // nulling variable so it displays BLANK once again on the form
// Loops through and displays order names in the orders list
for (String name : orders) {
System.out.println(name + " in orders List");
}
return null;
}
}
这是我的 jsf 页面:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="3">
<h:outputText value="Enter Order Name >>" />
<h:inputText id="orderName" value="#{testBean.orderName}" label="# {testBean.orderName}" />
<h:message for="orderName" />
</h:panelGrid>
<h:commandLink value="Enter Order" actionListener="#{testBean.processDataTable}">
<f:ajax execute="orderName dataTable" render="orderName dataTable" />
</h:commandLink>
<h:dataTable id="dataTable" value="#{testBean.orders}" var="order">
<f:facet name="header">Orders Entered Shown Below: </f:facet>
<h:column>
<h:outputText value="#{order}" />
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
【问题讨论】:
标签: ajax jsf commandlink session-scope view-scope