Ich verwende Facelet-Templating und ich denke, ich bin in ein Problem mit ui:define und der JSF-Lebenszyklus laufen. Meine template.xhtml enthält ein festes Menü in der Kopfzeile, vereinfacht es hat Links wie diese:
<h:commandLink value="Click Me">
<f:ajax update="#{myBean.listener}" render="contentpanel"/>
</h:commandLink>
Die Datei template.xhtml enthält auch eine ui:insert-Anweisung:
<ui:insert name="content">
<h:outputLabel value="content placeholder"/>
</ui:insert>
Jetzt habe ich eine content.xhtml, die wie folgt aussieht:
<ui:composition template="template.xhtml">
<ui:define name="content">
<h:panelGroup id="contentpanel"/>
</ui:define>
</ui:composition>
So viel zur Einführung. Wenn ich den Commandlink 'Click Me' anklicke, rufe ich meinen Listener auf. Dieser Listener setzt eine Referenz in einer Backingbean, um den Inhalt dynamisch zu laden, basierend auf dem Link, den ich angeklickt habe.
Dieses Rendering erfolgt nicht, wenn ich das erste Mal den Befehlslink drücke. Nun, es sieht so aus, als ob es zuerst das Re-Rendering macht und dann den Listener aufruft, anstatt andersherum. Wenn ich also zum ersten Mal klicke, scheint nichts zu passieren. Wenn ich zum zweiten Mal klicke, sehe ich den Inhalt, der für den ersten Klick festgelegt wurde. Wenn ich zum dritten Mal klicke, sehe ich den Inhalt des zweiten Klicks.
Ich denke, es liegt daran, dass die ui:define-Ansicht bereits in der Phase "Restore View" des JSF-Lebenszyklus neu erstellt wird. Irgendwelche Ideen, wie man dies überwinden kann?
UPDATE
Es scheint, dass meine Annahme falsch war. Die Ursache dafür scheint etwas anderes zu sein. Die #{myBean.listener}
hat eine @SessionScoped @ManagedProperty
die aktualisiert wird, nachdem der CommandLink angeklickt wurde. Das Inhaltspanel lädt die Daten tatsächlich über den #{myBean.data}
das ist @RequestScoped
. Diese #{myBean.data}
die Daten nicht korrekt zurückgeladen hat. Ich habe das Problem gelöst, indem ich die getData()
Methode direkt mit der @SessionScoped
Bohne.
Das könnte ein wenig verwirrend sein. Aber meine Schlussfolgerung: Es tut arbeiten, um eine Komponente, die über Facelet-Templating geladen wird, teilweise zu rendern ( ui:define / ui:insert
)