2010-07-07 24 views
7

Motivazione: Voglio ridurre le dimensioni della pagina quando si accede, quindi ho pensato che il rendering pigro su modalPanels sarebbe stato d'aiuto. L'idea è di rendere il modalPanel quando l'utente fa clic sul link che lo visualizza.modalPanel rendering pigro quando visualizzato

Desidero rendere pigro su rich:modalPanel quando viene fatto clic sul collegamento per visualizzarlo. Per raggiungere questo obiettivo ho trovato un modo:

Codice del modalPanel, avvolto all'interno di un a4j:outputPanel

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

Codice della backing bean (scope di sessione):

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

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

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

Codice della pagina dove è stato invocato:

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

Problemi:

  • La modalPanel deve essere avvolto all'interno di un a4j:outputPanel perché reRendering direttamente l'modalPanel non funziona (ho mai capito perché).

  • Dopo il rendering, è necessaria una richiesta aggiuntiva per impostare il valore di rendering su falso (il bean è impostato sulla sessione). Altrimenti se ricarichiamo la pagina non ci sarà alcun rendering pigro perché il valore è stato impostato su true.

  • Il supporto bean deve gestire una proprietà di mantenere lo stato di ogni modalPanel, anche se questa proprietà è impostata true ogni volta che il collegamento è scattato ed impostato false quando la richiesta è terminata. Ho provato a mantenere lo stato rendered con le variabili JS ma non sembra funzionare (vengono letti solo una volta che la pagina è stata caricata e mai più).

Un modo più elegante per farlo?

risposta

7

C'è una bella soluzione per quanto riguarda la tua domanda. Tutto ciò che serve è un modo per rilevare il postback e un paio di xhtml.

Prima di tutto abbiamo bisogno di un fagiolo che aiuterà con l'indicazione di postback

public class HelperBean { 

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

} 

empty.xhtml - per un contenuto vuoto

<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 - per avvolgere la definizione modale

<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 - per gestire l'inserimento delle suddette 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 usano

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

Ora empty.xhtml quando la pagina viene caricata sarà incluso fino btnSubmit viene cliccato.


Riguardo ai problemi che hai citato (1):

componenti Re-rendering con l'attributo reso è un po 'accattivante. Quando l'espressione di rendering viene valutata come falso, nessun markup viene inviato al client. Pertanto, fornire l'id del componente none render sull'attributo reRender non funzionerà mai perché non esiste tale id sul lato client (DOM).

+0

Sembra una soluzione pulita. Ci proverò. Se funziona, la taglia è tua :) – pakore

+0

Ha funzionato bene! Grazie. – pakore

+0

Grande, felice che sia stato d'aiuto. –

1

penso che dovresti creare xhtml (facelet) separato del pannello modale e usare ui: include e che sul link fai clic sul link non c'è bisogno di proprietà booleane di.

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

Il modalPanel è già un xhtml separato inserito con 'ui: include'. Quando si include un file, jsf incolla il codice all'interno del contenitore, quindi è pensato per essere renderizzato, è reso. – pakore

+0

hai ragione, ma questo è l'unico modo per ui: include. Il rendering pigro potrebbe non essere possibile. Controllerò se c'è qualche soluzione ..... Buon giorno – TaherT

1

Un'altra soluzione consiste nel impostare l'attributo di rendering della finestra di dialogo modale nella struttura del componente JSF. Quindi è wont't bisogno di un backing bean supplementare che deve gestire una proprietà per mantenere lo stato di ogni 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:

Aprire il pannello:

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

chiudere il pannello:

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

Il modalpanel:

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