2010-04-17 4 views
2

J'essaie actuellement d'ajouter dynamiquement un nouveau composant à l'arborescence des composants JSF lors d'une requête ajax.Comment ajouter dynamiquement un composant dans JSF2 lors d'une requête Ajax

En fait, j'ajoute un enfant au composant UIViewRoot dans mon AjaxBehaviorListener qui est déclenché côté serveur pendant le processus de requête ajax.

Le problème est que le nouveau composant n'est pas rendu. Il semble que ce composant ne soit pas pris en compte dans la phase de réponse au rendu.

Pourriez-vous m'aider sur cette question?

Cordialement,

Guillaume

Répondre

1

Au lieu d'essayer d'ajouter le composant dynamiquement lors de la demande de paiement ajax, essayez de définir le composant initial et le réglage est rendu ce tag à false. Le contenu du composant peut ensuite être rempli avec la requête ajax et l'attribut rendu retourné pour afficher l'attribut.

+0

En fait, comment voulez-vous changer l'attribut de composant (ou une propriété) afin de le rendre lors de la demande AJAX? Utiliseriez-vous un backing bean? –

+0

Vous voulez juste que l'évaluation de certains EL passe de faux à vrai. Cela pourrait être une propriété booléenne Backing Bean, ou n'importe quel bit arbitrairement complexe de EL (Expression Language) –

2

Cette solution fonctionne dans le cas où vous le savez avant que l'ajax demande le composant à ajouter. Mais si vous ne savez pas quel composant ajouter, cela ne fonctionne pas.

Je peut-être trouvé une solution:

Ma solution est de mettre en œuvre mon habitude PartialViewContext et utiliser la méthode startInsertAfter ou startInsertBefore du PartialResponseWriter.

Cela fonctionne, mais vous devez mettre le composant ajouté comme transitoire. (UiComponent.setTransient (Boolean.TRUE);)

Cordialement,

Guillaume

+0

C'était juste un exemple! Vous pouvez implémenter 'addOutputText()' de plusieurs façons. Par exemple, vous pouvez passer un objet qui étend quelque chose comme 'AbstractComponentFactory'. Cette fabrique crée une sorte de 'UIComponent' (' public UIComponent AbstractComponentFactory.createComponent() '). J'espère que c'est compréhensible. Juste besoin d'imagination. –

2

Cela fonctionne pour moi:

Bean se liant à la tenue UIComponent sous lequel vous souhaitez ajouter d'autres UIComponents dynamique devrait être demande scope sinon il peut jeter quelques exceptions désagréables (ne me demandez pas pourquoi):

@ManagedBean 
    @RequestScoped 
    public class AddressEditorBean { 
// session bean reference for holding id number line and model 
     @ManagedProperty(value = "#{addressValueBean}") 
     private AddressValueBean address;  
     public String addOutputText() { 
      HtmlOutputText text = new HtmlOutputText(); 
      int c = address.getC(); 
      text.setValue("new text! " + c); 
      text.setId("id" + c++); 
      address.setC(c);    // hold id number line in sessionbean 
      address.getComps().add(text); // hold new uicomponent in session bean to be able to rebuild it 
      panel.getChildren().clear(); // need to clear children and add them all again, 
      panel.getChildren().addAll(address.getComps()); // otherwise there are problems with duplicate children (bug?) 
      return "success"; 
     } 

     public HtmlPanelGroup getPanel() { 
      return panel; 
     } 

     public void setPanel(HtmlPanelGroup pane) { 
      if (panel == null) { 
       this.panel = pane; 
       if (panel != null) { 
        panel.getChildren().addAll(address.getComps()); 
       } 
      } else { 
       this.panel = pane; 
      } 
     } 
    } 

extrait de code de la page. Ajouter dynnamically composants à <h:panelGroup>

<h:form> 
     <h:panelGroup id="section" binding="#{addressEditorBean.panel}"> 

     </h:panelGroup> 
     <h:commandButton value="add new text" action="#{addressEditorBean.addOutputText}"> 
      <f:ajax execute="@this" render="section" event="action"/> 
     </h:commandButton> 
    </h:form> 

En Session bean je tiens modèle dynamique réelle pour que je puisse le reconstruire après rechargement de la page:

@ManagedBean 
@SessionScoped 
public class AddressValueBean extends ValueBean<Address> { 

    private int c = 0; 
    private List<UIComponent> comps = new ArrayList<UIComponent>(); 

    public AddressValueBean() { 
     setValue(new Address()); 
    } 

    public int getC() { 
     return c; 
    } 

    public void setC(int cn) { 
     this.c = cn; 
    } 

    public List<UIComponent> getComps() { 
     return comps; 
    } 

    public void setComps(List<UIComponent> comps) { 
     this.comps = comps; 
    } 
} 
Questions connexes