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 следует передавать независимо от того, загружена страница или нет.
Я использую:
- JSF Mojarra (2.2.6)
- Spring: "просмотр области видимости" выполняется на примере https://github.com/michail-nikolaev/primefaces-spring-scopes/blob/master/primefaces-scopes-test/src/main/java/org/nkey/primefaces/scopes/test/spring/scope/ViewScope.java
- Простые лица (5.1)
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;
}