2010-07-07 6 views
7

Motivación: Quiero reducir el tamaño de la página cuando se accede, así que pensé que el renderizado lento en modalPanels ayudaría. La idea es presentar el modalPanel cuando el usuario haga clic en el enlace que lo muestra.modalPanel lazy rendering cuando se muestra

Quiero renderizar vago en rich:modalPanel cuando se hace clic en el enlace para mostrarlo. Para lograr esto que he encontrado una manera:

Código del modalPanel, envuelto dentro de una

<a4j:outputPanel id="a4jPanel"> 
    <rich:modalPanel id="panel" rendered="#{bean.renderPanel}"> 
     <!-- here modalPanel things --> 
    </rich:modalPanel> 
</a4j:outputPanel> 

Código a4j:outputPanel

del bean de respaldo (ámbito de sesión):

public boolean isRenderPanel() { 
    return renderPanel; //default value is false; 
    } 

    public void setRenderPanel(boolean value){ 
      this.renderPanel=value; 
    } 

    public setRenderFalse(){ 
      this.setRenderPanel(false); 
    } 

Código de la página en la que se invoca:

<a4j:form> 
<a4j:jsFunction name="setRenderFalse" action="#{user.setRenderFalse}"/> 
<a4j:commandLink value="render and show" oncomplete="Richfaces.showModalPanel('panel');setRenderFalse();" reRender="a4jPanel"> 
<f:setPropertyActionListener target="#{user.renderPanel}" value="true" /> 
</a4j:commandLink> 
</a4j:form> 

Problemas:

  • El modalPanel tiene que ajustarse dentro de un a4j:outputPanel porque reRendering directamente la modalPanel no funciona (que nunca he entendido por qué).

  • Después de representarlo, se necesita una solicitud adicional para establecer el valor de representación en falso (el bean tiene una sesión de ámbito). De lo contrario, si volvemos a cargar la página no habría ninguna representación diferida porque el valor se estableció en true.

  • frijol El respaldo tiene que manejar una propiedad para mantener el estado de cada modalPanel, aunque esta propiedad se establece en true cada vez que se hace clic en el enlace y se puso a false cuando la solicitud esté terminado. Intenté mantener el estado rendered con variables JS, pero parece que no funciona (solo se leen una vez que se carga la página y nunca más).

¿Alguna forma más elegante de hacer esto?

Respuesta

7

Hay una buena solución para su pregunta. Todo lo que se necesita es una forma de detectar la devolución de datos y un par de xhtmls.

En primer lugar necesitamos un grano que le ayudará con indicación de devolución de datos

public class HelperBean { 

    public boolean isPostback() { 
     FacesContext context = FacesContext.getCurrentInstance(); 
     return context.getRenderKit().getResponseStateManager().isPostback(context); 
    } 

} 

empty.xhtml - un contenido en blanco

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:c="http://java.sun.com/jstl/core" 
    xmlns:a4j="http://richfaces.org/a4j" 
    xmlns:rich="http://richfaces.org/rich"> 

</ui:composition> 

modal.xhtml - para envolver la definición modal

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:c="http://java.sun.com/jstl/core" 
    xmlns:a4j="http://richfaces.org/a4j" 
    xmlns:rich="http://richfaces.org/rich"> 

    <rich:modalPanel id="myLazyModal"> 
     <h:outputText value="Modal Content"/> 
    </rich:modalPanel> 
</ui:composition> 

lazyModal.XHTML - para el manejo de la inclusión de los anteriores xhtmls

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:c="http://java.sun.com/jstl/core" 
    xmlns:a4j="http://richfaces.org/a4j" 
    xmlns:rich="http://richfaces.org/rich"> 

    <a4j:include id="lazyModal" layout="block" 
     viewId="#{helperBean.postback ? 'modal.xhtml' : 'empty.xhtml'}"/> 
</ui:composition> 

finalmente lo utilizan

<h:form id="frmTest"> 
     <a4j:include id="lazyModalContainer" layout="block" viewId="lazyModal.xhtml"/> 
     <a4j:commandButton id="btnSubmit" value="Submit" reRender="lazyModalContainer" 
      oncomplete="Richfaces.showModalPanel('myLazyModal');"/> 
    </h:form> 

Ahora se incluirá empty.xhtml cuando la página se carga hasta que se hace clic en btnSubmit.


En cuanto a los problemas que usted ha mencionado (1):

componentes re-representación con el atributo prestado es un poco pegajoso. Cuando la expresión procesada se evalúa como falsa, no se devuelve ninguna marca al cliente. Por lo tanto, el suministro de la identificación del componente no representado al atributo reRender nunca funcionará porque no existe dicha identificación en el lado del cliente (DOM).

+0

Parece una solución limpia. Voy a probarlo. Si funciona, la recompensa es suya :) – pakore

+0

¡Funcionó muy bien! Gracias. – pakore

+0

Genial, me alegro de que haya ayudado. –

1

creo que debe hacer xhtml (facelet) por separado del panel modal y usar ui: incluir y luego en el enlace hacer clic en el enlace no es necesario que tenga una propiedad booleana.

enter code here : <ui:include src="modalPanel path">, <a4j:commandLink id="abclink" oncomplete="#{rich:component('yourPanelname')}.show()" reRender="yourPanelForm"/> 
+0

El modalPanel ya es un XHTML separada insertada con 'ui: include'. Cuando incluye un archivo, jsf pega el código dentro del contenedor, por lo tanto, se debe representar, se procesa. – pakore

+0

ya tienes razón, pero esa es la única forma en que ui: incluir. Lazy Render es posible que no sea posible. Voy a comprobar si hay alguna solución ..... Buen día – TaherT

1

Otra solución es establecer el atributo render de su modalpanel mediante programación en el árbol de componentes JSF. Por lo que hace ningún necesita un bean de respaldo adicional que tiene que manejar una propiedad para mantener el estado de cada modalPanel:

Managed Bean:

public void togglePanel(ActionEvent event) { 
    UIComponent component = event.getComponent(); 
    String forId = (String) component.getAttributes().get("for"); 

    FacesContext currentInstance = FacesContext.getCurrentInstance(); 
    UIComponent findComponent = ComponentFinder.findComponent(currentInstance.getViewRoot(), forId); 
    findComponent.setRendered(!findComponent.isRendered()); 
} 

Vista:

Abra el panel:

<a4j:commandLink actionListener="#{myBean.togglePanel}" value="Open"> 
<f:attribute name="for" value="targetPanelId" /> 

cerrar el panel:

<a4j:commandLink id="closePanel" actionListener="#{myBean.togglePanel}" value="someLabel"> 
<f:attribute name="for" value="targetPanelId" /> 

El modalpanel:

<a4j:outputPanel ajaxRendered="true"> 
     <rich:modalPanel id="targetPanelId" width="800" height="500" rendered="false" showWhenRendered="true">