vida tipos sintaxis fases explicacion elementos concepto ciclo bean alertas jsf facelets view-scope postconstruct

tipos - ¿Por qué @PostConstruct devuelve la devolución de llamada cada vez que Bean está @ViewScoped? JSF



phaselistener jsf (5)

Como dijo otro, yo diría que lo mejor que puede hacer es soltar el enlace de componentes (no lo necesita aquí).

Pero agregaría que puede lograr lo mismo que intenta hacer de una manera más orientada a objetos mediante el uso de parámetros de acción, como este:

<h:commandButton value="Click" action="#{testBean.action(item)}"/>

... y en tu código java:

public void action(Item item){ System.out.println("Clicked!!" + item); }

Estoy usando datatable en la página y usando el atributo de enlace para vincularlo a mi bean de respaldo. Este es mi código:

<?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:p="http://primefaces.prime.com.tr/ui"> <h:head> <title>Facelet Title</title> </h:head> <h:body> <h:form prependId="false"> <h:dataTable var="item" value="#{testBean.stringCollection}" binding="#{testBean.dataTable}"> <h:column> <h:outputText value="#{item}"/> </h:column> <h:column> <h:commandButton value="Click" actionListener="#{testBean.action}"/> </h:column> </h:dataTable> </h:form> </h:body> </html>

Este es mi bean: -

package managedBeans; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; import javax.faces.component.html.HtmlDataTable; @ManagedBean(name="testBean") @ViewScoped public class testBean implements Serializable { private List<String> stringCollection; public List<String> getStringCollection() { return stringCollection; } public void setStringCollection(List<String> stringCollection) { this.stringCollection = stringCollection; } private HtmlDataTable dataTable; public HtmlDataTable getDataTable() { return dataTable; } public void setDataTable(HtmlDataTable dataTable) { this.dataTable = dataTable; } @PostConstruct public void init(){ System.out.println("Post Construct fired!!"); stringCollection = new ArrayList<String>(); stringCollection.add("a"); stringCollection.add("b"); stringCollection.add("c"); } public void action(){ System.out.println("Clicked!!"); } }

Por favor, dime por qué está disparando @PostConstruct cada vez que hago clic en el botón? Debería disparar solo una vez, siempre que esté en la misma página porque mi bean está @ViewScoped. Además, si elimino el atributo de enlace, todo funciona bien y la devolución de llamada de @PostConstruct se activa solo una vez. Entonces, ¿por qué cada vez que uso un atributo de enlace? Necesito un atributo de enlace y quiero realizar tareas de inicialización como recuperar datos del servicio web, etc. solo una vez. ¿Que debería hacer? ¿Dónde debería escribir mi tarea de inicialización?


Es interesante que cuando utiliza el enlace de componentes en un bean con ámbito de vista, el alcance de la vista se rompe.

No estoy seguro de si eso es un error en JSF2, primero tendría que leer toda la especificación JSF2. Hasta ahora, lo mejor es soltar el enlace del componente por el momento y pasar el elemento seleccionado a través de la nueva sintaxis del argumento del método EL 2.2:

<h:dataTable var="item" value="#{testBean.stringCollection}"> <h:column> <h:outputText value="#{item}"/> </h:column> <h:column> <h:commandButton value="Click" action="#{testBean.action(item)}"/> </h:column> </h:dataTable>

Ver también:

Actualización (diciembre de 2012): este es de hecho un error en JSF2. Es un problema de huevo de gallina. Los beans de ámbito de vista se almacenan en el estado de vista JSF. Por lo tanto, los beans de ámbito de vista solo están disponibles después de la fase de restauración de la vista. Sin embargo, el atributo de binding ejecuta durante la fase de restauración de la vista, mientras que los beans de ámbito de vista todavía no están disponibles. Esto provoca la creación de una nueva instancia de bean con ámbito de vista, que luego se reemplaza por el bean de ámbito de vista real que se almacenó en el estado de la vista JSF restaurada.

Esto se informa como JSF issue 1492 y JSF spec isssue 787 que se fijará para JSF 2.2. Hasta entonces, la mejor opción es utilizar binding exclusivamente en los granos seleccionados, o buscar formas alternativas para los requisitos funcionales particulares.

Actualización (marzo de 2015): la solución JSF 2.2 se transfirió a Mojarra 2.1.18. Entonces, si todavía está utilizando JSF 2.0 / 2.1, será mejor que actualice a al menos esa versión. Ver también ao ¿Qué es el enlace de componentes en JSF? ¿Cuándo se prefiere usar? y JSTL en Facelets JSF2 ... tiene sentido?


La respuesta del balusc me ayudó mucho, me gustaría decir que tuve ese error con mojarra versión 2.1.7, actualmente estoy usando 2.1.29-01 lanzado en enero de 2015 y este error está solucionado, mi problema era vinculante. tabview a un bean viewscoped. Con esta versión no tengo ese error y el enlace y postconstrucción funciona bien. Uso Jboss 5.2 y tengo que usar mojarra 2.1.x, así que espero que esta respuesta ayude a otras personas en la misma situación.

http://mvnrepository.com/artifact/com.sun.faces/jsf-api/2.1.29-01 http://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.1.29-01


Otra solución:

  • Enlazando la HtmlDataTable en un Bean de alcance de solicitud.
  • Inyecte este bean de ámbito de solicitud en view bean de ámbito.

JBoss Seam usa esta solución para unir componentes JSF a un componente de ámbito de conversación.


Si tiene un bean viewcoped y desea conservar los valores que se ingresaron en el formulario o no desea que se active postconstruct, debe devolver null desde su método de acción.

Si devuelve algún resultado (por ejemplo, no válido) y luego señala el resultado no válido en la misma página usando faces-config.xml, entonces el bean viewscoped se vuelve a crear y, por lo tanto, hace que postconstruct se vuelva a disparar.