2010-08-18 3 views
1

Mon but est de charger dynamiquement le contenu d'un composant JSF 2.0. Le cas d'utilisation est le suivant: l'utilisateur clique sur un bouton, ce qui ouvre un panneau modal avec des contenus lourds via AJAX. En raison de sa lourdeur, je veux retarder le chargement jusqu'à ce que l'utilisateur en ait vraiment besoin. Si l'utilisateur ferme ce panneau, il n'est pas réellement supprimé de DOM, mais simplement effacé. Si l'utilisateur clique à nouveau sur le bouton d'initialisation, le panneau précédemment chargé s'affiche.JSF 2.0: Retard rendu contenu du composant (composite) jusqu'à un nouveau rendu appel AJAX il

Je sais que je peux empêcher le rendu de contenu en utilisant rendered="#{cc.attrs.visibilityState == 'hidden'}" et que je peux re-rendre le composant via l'appel JSF AJAX. Cependant, comment puis-je ajuster les attributs d'un composant composite à la volée de sorte que la deuxième fois autour du composant rende réellement?

1) Je sais que je pouvais faire:

<h:outputLink>Foo 
    <f:ajax event="click" render="theComponentIWantToUpdate" listener="#{someBean.someMethod()}" /> 
</h:outputLink> 

Et puis réglez les attributs theComponentIWantToUpdate programme (pour changer la valeur de #{cc.attrs.visibilityState}) de sorte qu'il serait effectivement rendu avec le contenu complet. Mais comment faire cela?

2) Aussi, le problème est que je ne veux pas mettre à jour theComponentIWantToUpdate chaque fois que j'appuie sur le bouton, seulement la première fois (voir l'analyse de rentabilisation). Comment puis-je définir une évaluation pour <f:ajax /> appel pour cela? Il a l'attribut disabled, mais il ne commande que le rendu du gestionnaire AJAX (non évalué chaque fois que le lien est appuyé).

3) De plus, je souhaite d'abord faire du javascript personnalisé lorsque le lien est cliqué et exécuter uniquement la requête AJAX via javascript en utilisant jsf.ajax.request(). Cependant, cette fonction ne prend pas en charge la fourniture listener attribut donc je ne veux pas comment exécuter une méthode de backing bean avec javascript brut jsf.ajax.request() appel? Il existe en fait une question similaire sans réponses appropriées (voir JSF 2.0 AJAX: jsf.ajax.request to call method not only rerender an area of page).

+0

Ok je choisir ma propre solution partielle acceptée un pour le moment. Si quelqu'un a de meilleures suggestions, je serai heureux de changer cette sélection :) –

Répondre

1

Une solution partielle:

Voici mon lien qui envoie un AJAX demande (à l'intérieur d'une pièce composite):

<h:form> 
    <h:outputLink styleClass="modlet-icon"> 
     <f:ajax event="click" render=":#{cc.clientId}:modalWindow:root" listener="#{modalWindowBean.enableContentRendering(cc.clientId, 'modalWindow')}" /> 
    </h:outputLink> 
</h:form> 

L'auditeur appelle cette méthode:

public class ModalWindowBean { 
    ... 

    public void enableContentRendering(String clientId, String windowId) { 
     UIComponent component = FacesContext.getCurrentInstance().getViewRoot().findComponent(clientId + ":" + windowId); 
     component.getAttributes().put("contentRenderingEnabled", true); 
    } 
} 

Ici est mon objectif à rendre:

<modalWindow:modalWindow id="modalWindow"> 
    <quickMenu:quickMenuOverlay id="quickMenuOverlay" /> 
</modalWindow:modalWindow> 

ModalWindow enveloppe simplement la cible dans un joli panneau de fenêtre. Dans ModalWindow:

<composite:implementation> 
    <h:outputScript library="component/modalWindow" name="modalWindow.js" target="head" /> 
    <h:outputStylesheet library="component/modalWindow" name="ModalWindow.css" /> 

    <h:panelGroup id="root" layout="block" styleClass="modalWindow hide"> 
     <ui:fragment rendered="#{cc.attrs.contentRenderingEnabled}"> 
      ...all the wrapping elements with <composite:insertChildren /> within it 
      <script type="text/javascript"> 
       // Fade it in 
       var win = ModalWindow.getInstance('#{cc.clientId}'); // this gets the instance, available everywhere 
       win.position(#{cc.attrs.left}, #{cc.attrs.top}); 
       win.resize(#{cc.attrs.width}, #{cc.attrs.height}); 
       win.fadeIn(); 
      </script> 
     </ui:fragment> 
    </h:panelGroup> 

    <ui:fragment rendered="#{!cc.attrs.contentRenderingEnabled}"> 
     <script type="text/javascript"> 
      // Initialize modalWindow when it is rendered for the first time 
      var win = new ModalWindow('#{cc.clientId}'); // will be publicly available through ModalWindow static methods 
     </script> 
    </ui:fragment> 

</composite:implementation> 

Le problème? La requête AJAX est envoyée à chaque fois que l'utilisateur clique sur le bouton (la fenêtre est ainsi rechargée et effacée à chaque fois). Je dois être capable de contrôler quand/si la requête AJAX est réellement envoyée.

Tout ce genre de choses me fait manquer Apache Wicket, bien que je ne sais pas comment je ferais cela avec toute façon :)

Questions connexes