h:commandButton не работает с компонентом JSF во время загрузки страницы

Проблема:h:commandButton ajax не работает с bean-компонентом JSF во время загрузки страницы.

Имеется 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://xmlns.jcp.org/jsf/html"
      xmlns:co="http://java.sun.com/jsf/composite/standart/components"> 

    <h:form id="myForm"> 
        <div><h:outputLabel value="My name is #{myViewBean.name}" /></div>
        <h:commandButton
            action="#{myViewBean.actRedirectToAnotherView()}" 
            value="Redirect"/>                
        <h:dataTable value="#{myViewBean.bigList}" var="entity">
            <h:column>
                #{entity}
            </h:column>
        </h:dataTable>
    </h:form>
</html>

И управляемый вид bean-объекта "MyViewBean":

package mypackage;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Named;
import org.springframework.context.annotation.Scope;

@Named
@Scope(value = "view")
public class MyViewBean {

    private static int beanNrCounter = 0;
    private static final List<String> bigList = new ArrayList();
    static {
        for (int i = 0; i < 100000; i++) {
            bigList.add("Item in big list " + i);
        }
    }

    private final String name;

    public MyViewBean() {
        beanNrCounter++;
        name = "BEAN NR " + beanNrCounter;
        System.out.println("Created MyViewBean with name " + name);  
    }

    public String actRedirectToAnotherView() {
        String viewName = "anotherView.jsf";//actually some complex operation which decides where to redirect user 
        System.out.println("Redirecting to another view " + viewName );
        return viewName + "&faces-redirect=true";
    }

    public String getName() {
        return name;
    }

    public List<String> getBigList() {
        return bigList;
    }

}

Если я нажимаю кнопку "Redirect" во время загрузки страницы, метод "actRedirectToAnotherView" не выполняется, а создается другой компонент "MyViewBean". Если я нажимаю кнопку, то страница уже загружена, все работает как положено.

Я проверил, что затем нажимается кнопка "Перенаправить", если страница загружается с параметром формы javax.faces.ViewState передается с сообщением ajax, но если страница загружается - javax.faces.ViewState отсутствует (поэтому, конечно, новое представление создано).

Если я изменю область действия управляемого компонента на "запрос", проблема остается (кнопка "Перенаправление" все еще не работает, actRedirectToAnotherView не выполняется).

Как я могу исправить поведение ajax во время загрузки страницы? Мне кажется, что javax.faces.ViewState известен на стороне клиента, как только к MyViewBean осуществляется доступ, поэтому javax.faces.ViewState следует передавать независимо от того, загружена страница или нет.

Я использую:

1 ответ

Посмотрите на этот пример, надеюсь, вы найдете его полезным

Facelets:

<h:form>
    <h:commandLink value="show" action="#{showProducts.toggleShow}">
        <f:ajax render="products"/>
    </h:commandLink>
    <h:panelGroup id="products">
        <h:dataTable var="product" value="#{showProducts.products}" rendered="#{!showProducts.show}">
            <h:column>#{product.name}</h:column>
        </h:dataTable>
    </h:panelGroup>
</h:form>

и для управляемых бобов

private List<Product> products;

@PostConstruct
public void init() {
    products = this.getProductManager().getProducts();
}

public List<Product> getProducts() {
    return products;
}
Or if it actually needs to be lazily loaded, then rather do so:

private List<Product> products;

public List<Product> getProducts() {
    if (products == null) {
        products = this.getProductManager().getProducts();
    }
    return products;
}
Другие вопросы по тегам