Ich habe ein seltsames Problem beim Rendern von JSF2 (Facelet) Seiten. Es ist die übliche Seite, die eine id
über GET
empfängt und das Objekt anzeigt. Das Objekt hat eine Liste <> im Inneren, und das Problem ist, dass manchmal diese Liste nichts druckt und manchmal ich refresh und druckt die Liste teilweise (alle Elemente, aber nicht alle Informationen über sie). Es passiert auch mit anderen Objektattributen (einige Daten). Ich habe mit etwas Protokollierung überprüft und die Informationen sind korrekt aus der DB und dem Objekt set
s die Informationen erhalten.Einige Daten von JSF2 Bean aus der Datenbank zur Renderzeit nicht verfügbar
Ich bin mir ziemlich sicher, dass dies ist, weil preRenderView
kurz vor dem Rendern erfolgt, so dass die Bohne zufällig nicht verfügbar ist, wenn ich c:if
oder c:each
verwende. Für den zweiten Fall, vielleicht ui:repeat
would solve my problem?.
Meine Fragen sind:
- Wie kann ich dieses Problem beheben?
- Gibt es einen Weg in Facelets, um zB zu rendern. a
<section>
oder<time>
(wie in meinemdocument.xhtml
unten) und nicht den leeren Tag drucken, wenn gerendert auf false berechnet? Ich weiß, ich kannc:if
verwenden, aber gerendert wird in Facelets empfohlen. - Hat die DB Javabean
Document
auch (neben DocumentController)?
bitte auch, wenn es eine bessere Art und Weise zu tun, was ich tue (einer Seite, die ein id
über GET
und zeigt das Objekt erhält), bitte beraten. Ich bin total neu in JSF.
Btw, ich habe verworfen es ist wegen this problem.
DocumentController.java
@Named(value = "DocumentController")
@SessionScoped
public class DocumentController implements Serializable {
private String id;
private Document document;
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the Document
*/
public Document getDocument() {
return document;
}
/**
* @param Document the Document to set
*/
public void setDocument(Document document) {
this.document = document;
}
public void load() {
FacesContext ctx = FacesContext.getCurrentInstance();
if (ctx.isValidationFailed()) {
ctx.getApplication().getNavigationHandler()
.handleNavigation(ctx, "#{DocumentController.load}", "invalid");
return;
}
try (DataStore dst = new DataStore()) {
dst.connect();
document = dst.getDocument(id);
} catch (NoData | ConnectionError | IllegalArgumentException ex) {
ctx.getApplication().getNavigationHandler()
.handleNavigation(ctx, "#{DocumentController.load}", "invalid");
}
}
}
document.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:utils="http://java.sun.com/jsf/composite/utils"
template="template.xhtml">
<ui:define name="content">
<f:metadata>
<f:viewParam name="id" value="#{documentController.id}" required="true"/>
<f:event type="preRenderView" listener="#{documentController.load}"/>
</f:metadata>
...
<section rendered="#{not empty documentController.document.participants}">
<utils:participants
participants="#{documentController.document.participants}
cid="example"/>
....
</ui:define>
</ui:composition>
participants.xhtml
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<cc:interface>
<cc:attribute name="participants" type="java.util.List" required="true"/>
<cc:attribute name="cid" type="String" required="true"/>
</cc:interface>
<cc:implementation>
<table>
...
<tbody>
<c:forEach items="#{cc.attrs.participants}" var="participant">
<tr>
<td><a href="#">#{participant.name}</a></td>
<td>#{participant.lastName}</td>
<td>#{participant.role(cc.attrs.cid)}</td>
</tr>
</c:forEach>
</tbody>
</table>
</cc:implementation>
</ui:component>
Es scheint, was Sie tun möchten, ist zu verwenden, um eine 'h: dataTable' in Ihrem Verbundbauteil statt den Aufbau einer Tabelle selbst . Sehen Sie sich die Komponente an. Auch für Ihre zweite Frage könnten Sie, da es sich um Standard-HTML-Tags handelt, dann in ein 'ui: fragment' verpacken, das auch das' gerendert'-Attribut enthält und keinen zusätzlichen HTML-Code darstellt. –
Bei einigen Elementen würde ich lieber mein eigenes HTML5 anstelle von h: XXX verwenden. Auch dies würde das Problem nicht lösen, denn wie gesagt, es passiert auch mit meinem