ajax - showcase - primefaces tutorial español
¿Cómo apilar mensajes con el componente de mensajes PrimeFaces? (2)
Tengo una pregunta sobre el componente p: mensajes .
Primero, aquí está mi configuración:
- PrimeFaces: 4.0.3 (élite)
- JSF: MyFaces 2.0.2
- Servidor: WebSphere 8.5.0.2
Entonces, mi código:
test.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:head>
<f:facet name="first">
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</f:facet>
<meta http-equiv="cache-control" content="no-store,no-cache" />
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="expires" content="0" />
</h:head>
<h:body>
<div id="content">
<h:form id="form1">
<p:tooltip/>
<p:messages id="messages" showDetail="true" />
<p:remoteCommand async="true" autoRun="true" process="@this" partialSubmit="true" action="#{testBean.checkA}" />
<p:remoteCommand async="true" autoRun="true" process="@this" partialSubmit="true" action="#{testBean.checkB}" />
</h:form>
</div>
</h:body>
</html>
Test.java
import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.context.RequestContext;
@ManagedBean(name="testBean")
@ViewScoped
public class Test implements Serializable {
private static final long serialVersionUID = -1L;
public void checkA() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Message 1", null));
RequestContext.getCurrentInstance().update("form1:messages");
}
public void checkB() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,"Message 2", null));
RequestContext.getCurrentInstance().update("form1:messages");
}
}
Lo que hace este código es realmente simple. Cuando se carga la página, se realizan dos llamadas AJAX (checkA y checkB). He puesto un Thread.sleep(2000)
en check A para fines de prueba ya que quiero que termine después de la verificación B. Una vez que se finaliza un método, envía un mensaje a la IU.
Cuando cargo la página, veo que se hacen ambas llamadas AJAX. El CheckB se terminará primero, así que veré el "Mensaje 2" en mi página. Pero tan pronto como finaliza la verificación, el mensaje se reemplaza por "Mensaje 1". Lo que me gustaría hacer es agregar "Mensaje 1" a "Mensaje 2", para que el usuario vea ambos mensajes en la pantalla. ¿Hay alguna forma de hacerlo o es una limitación del componente?
En segundo lugar, como puede ver en mi código, tengo que llamar a RequestContext.getCurrentInstance().update("form1:messages");
para ver mis p:messages
actualizados. Si autoUpdate="true"
esta línea de código y agrego autoUpdate="true"
al componente, no funciona ...
Una cosa a tener en cuenta, desafortunadamente, no puedo cambiar la configuración del servidor ya que no lo administro y ya hay docenas de otras aplicaciones en él.
¡Gracias de antemano por tu ayuda!
El problema que tienes aquí es que los FacesMessages tienen alcance de solicitud . Como está realizando dos solicitudes ajax, cuando llegue al final de la segunda, el primer mensaje no estará disponible en ese momento.
Estás utilizando un bean @ViewScoped
que permanece activo hasta que dejas la vista, por lo que la solución debe tener allí un tipo de pila / cola que almacene los mensajes para mostrar. Cuando considere que se realizó la última solicitud, solo agregue todos sus mensajes a FacesContext
y borre la pila.
Otra opción sería realizar todas sus operaciones en el mismo método y mostrar los mensajes que desee después de eso. Disminuiría el tráfico de red al realizar una solicitud en lugar de dos, pero su elección parece interesante si desea representar partes específicas de la página antes que otras .
Acerca de su problema de actualización, recuerde que puede especificar la parte del formulario que desea actualizar directamente en la página. Intente agregar update="messages"
a sus etiquetas p:remoteCommand
. Acerca de que autoUpdate
no funciona, posiblemente el remoteCommand
de su partialSubmit
podría estar partialSubmit
problemas. Verifique la definición de ese atributo en los documentos de Primefaces :
parcialSubmit: permite la serialización de valores que pertenecen solo a los componentes parcialmente procesados.
Puede usar múltiples componentes p:message
:
<p:message id="message1"
for="message1ValidatorCall" />
<h:inputHidden id="message1ValidatorCall" value="message1ValidatorCall">
<f:validator validatorId="myValidator" />
</h:inputHidden>
<p:message id="message2"
for="message2ValidatorCall" />
<h:inputHidden id="message2ValidatorCall" value="message2ValidatorCall">
<f:validator validatorId="mySecondValidator" />
</h:inputHidden>
Debe considerar faces validators
si desea verificar o validar algo:
@FacesValidator("myValidator")
public class MyValidator implements Validator {
@Override
public void validate(FacesContext facesContext, UIComponent uiComponent, Object o) throws ValidatorException {
//validator logic
}
}