JSF 2.0: Preservando el estado del componente a través de múltiples puntos de vista

StackOverflow https://stackoverflow.com/questions/4605785

  •  25-09-2019
  •  | 
  •  

Pregunta

La aplicación web que estoy desarrollando utilizando MyFaces 2.0.3 / PrimeFaces 2.2RC2 se divide en un contenido y un área de navegación. En el área de navegación, que se incluye en varias páginas usando plantillas (es decir <ui:define>), hay algunos widgets (por ejemplo, un árbol de navegación, paneles plegables etc.) de la que desea conservar el estado del componente a través de puntos de vista.

Por ejemplo, digamos que estoy en la página principal. Cuando navego a una página de detalles del producto haciendo clic sobre un producto en el árbol de navegación, mis disparadores Java de código utilizando una redirección

navigationHandler.handleNavigation(context, null,
  "/detailspage.jsf?faces-redirect=true")

Otra manera de conseguir a la página de detalles sería haciendo clic directamente en un adelanto del producto que se muestra en la página principal. El <h:link> correspondiente nos llevaría a la página de detalles.

En ambos casos, se pierde el estado de expansión de mi árbol de navegación (un componente PrimeFaces árbol) y mis paneles plegables. Entiendo que esto es debido a que los resultados de redirección / h:link en la creación de una nueva vista.

¿Cuál es la mejor manera de hacer frente a esto? Ya estoy usando MyFaces orquesta en mi proyecto junto con su ámbito de conversación, pero no estoy seguro si esto es de alguna ayuda aquí (ya que tendría que obligar a la expansión / contraído de los widgets a un bean de respaldo ... pero por lo que sé, esto no es posible). ¿Hay una manera de decirle a la que JSF estados componentes se propaguen a la siguiente vista, si se asume que existe el mismo componente en esa vista?

supongo que podría necesitar un puntero en la dirección correcta aquí. Gracias!


Actualización 1: Me acaba de intentar unir los paneles y el árbol a un bean de ámbito de sesión, pero esto parece tener ningún efecto. Además, supongo que tendría que obligar a todos los componentes hijos (si los hay) de forma manual, por lo que este no parece ser el camino a seguir.

Actualización 2: Binding componentes de interfaz de usuario a la no petición en ámbito de los granos no es una idea buena (ver enlace que he publicado en un comentario más abajo). Si no existe un método más fácil, puede ser que tenga que proceder de la siguiente manera:

  • Cuando un panel se contrae o se expande el árbol, guardar el estado actual en un bean de respaldo de ámbito de sesión (! = Componente de interfaz de usuario en sí)
  • disposiciones de los componentes se almacenan en un mapa. La clave del mapa es (esperemos) único, identificación relativa del componente. No puedo utilizar todo el camino componente absoluta aquí, puesto que los ID de los contenedores de nomenclatura de los padres pueden cambiar si los cambios de vista, suponiendo que estos identificadores se generan mediante programación.
  • Tan pronto como un nuevo punto de vista se construye, recuperar disposiciones de los componentes del mapa y aplicarlos a los componentes. Por ejemplo, en el caso de los paneles, puedo establecer el atributo collapsed a un valor recuperado de mi bean de respaldo de ámbito de sesión.

Actualización 3: lo tengo trabajando como se ha descrito anteriormente. Para resumir, la solución es almacenar las propiedades relevantes en un bean de sesión con ámbito en lugar de hacer todo el UIComponent con ámbito sesión. Entonces, cuando el componente se re-construye después que ha ocurrido la navegación, establecer los valores de atributo mediante la recuperación de las propiedades almacenadas (utilizando EL), por ejemplo.

<p:panel collapsed="#{backingBean.collapsedState}" ... />

(Este es un ejemplo simplificado. Desde que estoy usando múltiples paneles, estoy usando un mapa para almacenar estas propiedades, como se describe anteriormente).

¿Fue útil?

Solución

Una solución sería utilizar beans de sesión con ámbito.

Otros consejos

¿Qué quiere decir con paneles plegables? Lo pregunto porque hay un componente que se puede cerrar, así como un componente. Estoy utilizando en el panel de navegación en mi proyecto. El accordianPanel tiene un atributo llamado "activeIndex". Esto es lo que hice en mi SessionBean para mantener el estado de mis fichas acordeón:

 private int tabIndex; //declared a private variable

    public SessionBean() {
       tabIndex = 100; //set the initial tab index to 100 so all tabs are closed when page loads.
    }

    public int getTabIndex(){
       return tabIndex;
    }

    public void setTabIndex(int tabIndex){
       this.tabIndex=tabIndex;
    }

in my navigation pane:



<p:accordionPanel activeIndex="#{sessionBean.tabIndex}" collapsible="true" autoHeight="false">
    <p:tab title="#{tab1_title}">
       <h:commandLink value="link here" action="target_page?faces-redirect=true" /><br/>
    </p:tab>
    <p:tab title="#{tab2_title}">
       <h:commandLink value="link here" action="target_page?faces-redirect=true" />
    </p:tab>
    <p:tab title="#{tab3_title}">
       <h:commandLink value="link here" action="target_page?faces-redirect=true" />
    </p:tab>
 </p:accordionPanel>

No estoy usando el componente árbol de navegación como el presentado mi proyecto con algunas dificultades que fueron superados fácilmente usando la accordionPanel, así que no puedo hablar de esa parte de su navegación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top