Hallo zusammen,
Ich beschäftige mich seit kurzem mit Java Server Faces und bin gerade dabei meine ersten praktischen Gehversuche mit mit Apache Myfaces-1.1.6 und Facelets-1.1.4 zu machen.
Ich habe ein einfaches Master/Detail Szenario umgesetzt (User Liste -> Detailansicht eines Users).
Was soweit auch wunderbar funktioniert, und genau das ist es was mich gerade etwas stutzig macht.
Ansatz:
Ich verwende zwei Managed Beans (UserMasterHandler, UserDetailHandler). Der UserMasterHandler enthält ein ListDataModel um eine List<User> in einem <h:datatable> darzustellen. Die einzelnen Einträge der Tabelle werden als <h:commandlink> dargestellt. Der commandlink verweisst auf eine action Methode (UserMasterHandler.showDetail()), die über createValueBinding() den aktuell gewählten User an die DetailUserBean bindet und als Rückgabewert einen String liefert, der auf die Detailansicht Seite "weiterleitet" (Navigationsregel in der faces-config.xml).
Ich habe diesen Ansatz teilweise aus einem Buch und habe ihn etwas abgewandelt (Unter anderem den Scope der Beans auf Request gesetzt). Was mich etwas wundert ist der Punkt, dass soweit ich das verstanden habe, Beans, die von JSF "gemanaged" werden bei einem ersten Zugriff initialisiert werden. In meinem Fall würde der UserDetailHandler durch createValueBinging von UserMasterBean.showDetail() zum ersten mal initialisiert werden. Da die Bean allerdings im Request Scope "lebt" müsste sie doch eigentlich neu initialisiert werden, sobald im nächsten Request (weiterleiten auf userDetail.xhtml) wieder auf sie zugegriffen wird. Das heißt eigentlich dürfte der gebundene User nicht mehr in der Bean existieren, da es sich ja um einen neuen Request und somit eine neue Instanz von UserDetailHandler handelt, oder? Oder befinde ich mich beim Aufruf von UserMasterHandler.showDetail() schon im Request für die Detailansicht?
Über Tipps, wie man solche Master/Detail Szenarien mit JSF elegant umsetzten kann wäre ich ebenfalls dankbar.
Gruß Luca
UserMasterHandler.java
UserDetailHandler.java:
userOverview.xhtml:
userDetail.xhtml:
faces-config.xml
Ich beschäftige mich seit kurzem mit Java Server Faces und bin gerade dabei meine ersten praktischen Gehversuche mit mit Apache Myfaces-1.1.6 und Facelets-1.1.4 zu machen.
Ich habe ein einfaches Master/Detail Szenario umgesetzt (User Liste -> Detailansicht eines Users).
Was soweit auch wunderbar funktioniert, und genau das ist es was mich gerade etwas stutzig macht.
Ansatz:
Ich verwende zwei Managed Beans (UserMasterHandler, UserDetailHandler). Der UserMasterHandler enthält ein ListDataModel um eine List<User> in einem <h:datatable> darzustellen. Die einzelnen Einträge der Tabelle werden als <h:commandlink> dargestellt. Der commandlink verweisst auf eine action Methode (UserMasterHandler.showDetail()), die über createValueBinding() den aktuell gewählten User an die DetailUserBean bindet und als Rückgabewert einen String liefert, der auf die Detailansicht Seite "weiterleitet" (Navigationsregel in der faces-config.xml).
Ich habe diesen Ansatz teilweise aus einem Buch und habe ihn etwas abgewandelt (Unter anderem den Scope der Beans auf Request gesetzt). Was mich etwas wundert ist der Punkt, dass soweit ich das verstanden habe, Beans, die von JSF "gemanaged" werden bei einem ersten Zugriff initialisiert werden. In meinem Fall würde der UserDetailHandler durch createValueBinging von UserMasterBean.showDetail() zum ersten mal initialisiert werden. Da die Bean allerdings im Request Scope "lebt" müsste sie doch eigentlich neu initialisiert werden, sobald im nächsten Request (weiterleiten auf userDetail.xhtml) wieder auf sie zugegriffen wird. Das heißt eigentlich dürfte der gebundene User nicht mehr in der Bean existieren, da es sich ja um einen neuen Request und somit eine neue Instanz von UserDetailHandler handelt, oder? Oder befinde ich mich beim Aufruf von UserMasterHandler.showDetail() schon im Request für die Detailansicht?
Über Tipps, wie man solche Master/Detail Szenarien mit JSF elegant umsetzten kann wäre ich ebenfalls dankbar.
Gruß Luca
UserMasterHandler.java
Code:
public class UserMasterHandler
{
private DataModel users = new ListDataModel();
public UserMasterHandler()
{
List<User> userList = new ArrayList<User>();
userList.add(new User("sebie"));
userList.add(new User("peter"));
userList.add(new User("max"));
users.setWrappedData(userList);
}
//geter & seter
public String showDetail()
{
User usr = (User)users.getRowData();
FacesContext fc = FacesContext.getCurrentInstance();
fc.getApplication().createValueBinding("#{userDetailHandler.user}").setValue(fc, usr);
return "showDetail";
}
UserDetailHandler.java:
Code:
public class UserDetailHandler
{
private User user;
public UserDetailHandler() { }
//geter & seter
}
userOverview.xhtml:
Code:
<ui:composition template="/pages/layout/main.xhtml">
<ui:define name="title">
User Overview
</ui:define>
<ui:define name="content">
<h:form>
<h:dataTable value="#{userMasterHandler.users}" var="userItem" style="border:1px solid #000000">
<h:column>
<f:facet name="header">User Name:</f:facet>
<h:commandLink action="#{userMasterHandler.showDetail}" value="#{userItem.name}"/>
</h:column>
</h:dataTable>
</h:form>
</ui:define>
</ui:composition>
userDetail.xhtml:
Code:
<ui:composition template="/pages/layout/main.xhtml">
<ui:define name="title">
</ui:define>
<ui:define name="content">
<h:outputText value="#{userDetailHandler.user.name}"/>
<h:form>
<h:commandButton action="#{userDetailHandler.back}" value="Back"/>
</h:form>
</ui:define>
</ui:composition>
faces-config.xml
Code:
<faces-config>
<application>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
<navigation-rule>
<from-view-id>/pages/userMaster.xhtml</from-view-id>
<navigation-case>
<from-outcome>showDetail</from-outcome>
<to-view-id>/pages/userDetail.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/pages/userDetail.xhtml</from-view-id>
<navigation-case>
<from-outcome>back</from-outcome>
<to-view-id>/pages/userMaster.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<managed-bean>
<managed-bean-name>userMasterHandler</managed-bean-name>
<managed-bean-class>jsf.handler.UserMasterHandler</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>userDetailHandler</managed-bean-name>
<managed-bean-class>jsf.handler.UserDetailHandler</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>