1

场景:我想通过使用 commandLink 使用 AJAX 在 JSF 中部分执行和呈现表单的一部分。由于这将通过 AJAX 完成,据我了解,ViewScoped 应该在 AJAX 请求之间保存页面中组件的值。

我在下面创建了一个示例,其中我有一个输入框,其中输入了订单名称,按下 commandLink(标记为“输入订单”),来自 inputText 的订单名称被添加到名为“订单”的 ArrayList 中,并且“订单”显示在 CommandLink 下方的数据表中。

来自 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 没有除空外显示。

如果我在添加“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>
4

1 回答 1

2

您正在使用 CDI-Bean,但您正在使用的 @ViewScoped-Annotation 是 JSF 特定的,并且在 CDI-Bean 中不起作用。

您可以改用 JSF-managedBean

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean(name="testBean")
@ViewScoped
public class DataTableTest implements Serializable { .. }

如果更改为 managedBean 不适合您,请查看特定于 CDI 的 @ConversationScope 或 Seam,其中您有一个 @ViewScoped 注释,它也适用于 CDI-Beans。

于 2012-11-22T10:04:43.143 回答