JSF: можно использовать только вид с привязкой к сеансу с помощью ajax commandlink

Сценарий: я хочу частично выполнить и отобразить часть формы в JSF, используя AJAX, с помощью commandLink. Поскольку это будет выполняться через AJAX, насколько я понимаю, ViewScoped должен хранить значения компонентов на странице между запросами AJAX.

Я создал пример ниже, где у меня есть поле ввода, в которое вводится имя заказа, нажимается commandLink (помеченная как «Ввести порядок»), имя заказа из inputText добавляется в список ArrayList с именем «orders», а значок « заказы »отображаются в таблице данных под CommandLink.

Запрос AJAX от CommandLink выполняет inputBox, который добавляет значение String к переменной «orderName». Запрос AJAX отправляет ActionEvent методу processDataTable (), который принимает значение «orderName» и добавляет его в список «заказов». Затем "orderName" обнуляется. Затем запрос AJAX отображает компонент inputText с обнуленным «orderName» и DataTable, который отображает все ранее введенные заказы, включая недавно добавленное «orderName» из этого запроса.

Проблема: код работает, если я использую bean-компонент SessionScoped, но НЕ, если я использую bean-компонент ViewScoped. Я добавил в код System.out.println (), чтобы увидеть, что происходит. Если я сделаю bean-компонент SessionScoped, то все будет работать по плану. Значение inputText устанавливается с помощью метода set, метод processOrder () добавляет строку «orderName» в список «orders», а DataTable повторно отображается, чтобы показать это добавленное имя. ...

В bean-компоненте ViewScoped значение «orderName» устанавливается равным значению компонента InputText, но внутри метода ProcessOrder () оно «null», добавляет «null» в список «orders», а DataTable не имеет ничего общего с показать кроме null.

Если я вручную добавлю orderName в processOrder () с помощью orders.add («Some Name») до добавления «orderName», «orders» будет содержать {«Some Order», «null»} и изменение в Orders по-прежнему НЕ перерисовывается с помощью AJAX.

Все отлично работает с bean-компонентом SessionScoped, а НЕ с bean-компонентом ViewScoped? Я также пробовал использовать атрибут Action с CommandLink вместо ActionListener, и та же история… работает с SessionScoped, но НЕ с ViewScoped.

Здесь я могу думать только о двух вещах: 1) Либо я упускаю важный момент в том, как AJAX и CommandLink работают вместе, и как должен работать ViewScoped (очень возможно); или 2) по какой-то причине, когда я отправляю вызов AJAX с помощью CommandLink, он обновляет страницу каждый раз, когда на нее щелкают, тем самым стирая предыдущие значения списка «заказов». Однако это все еще не объясняет, почему, если я вручную ввожу заказ в список, он по-прежнему не отображается в запросе AJAX с помощью bean-компонента ViewScoped, но БУДЕТ с bean-компонентом SessionScoped.

Помоги пожалуйста!!??

Вот мой код:

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>

person Nick Volk    schedule 22.11.2012    source источник


Ответы (1)


Вы используете 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.

person stg    schedule 22.11.2012