2016-01-20 10 views
0

Проблема: h: commandButton ajax не работает с компонентом JSF, а страница загружается.h: commandButton не работает с фасолью 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> 

И удалось посмотреть область действия боба «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; 
    } 

} 

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

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

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

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

Я использую:

+1

безопаснее всего заблокировать страницу во время загрузки или загрузки partsof содержания страницы лениво (= другое дело, чем, например, ленивый datatable) – Kukeltje

+0

Вероятно, Kukeltje обе предлагаемые решения будут работать. Просто блокировка - это не самое удобное для пользователя решение, и ленивая загрузка просто делает проблему менее заметной (для действительно медленного интернет-соединения она по-прежнему остается). Мне кажется странным, что почти все функции jsf ajax не будут работать так, как ожидалось, пока страница загружается (легко заметна при медленном подключении к Интернету) – Palladium

+0

Помимо конкретной проблемы, почему вы используете POST для навигации? Используйте ''. – BalusC

ответ

-1

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

Лицевые стороны:

<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> 

и управляемого Bean

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; 
} 
+1

Я не уверен, как это может помочь в моей ситуации (я не делаю никаких дорогих операций в getters, мой список статичен и загружается один раз во время запуска приложения). Проблема заключается в javax.faces.ViewState, который не передается во время загрузки страницы (страница ~ 7 Мб, так что естественно занимает пару секунд) – Palladium