最近のトレーニング コースでは、次の概念の証明を構築します。マスター (部門) テーブルと詳細 (従業員) テーブルの 2 つのテーブルを含む単一のビューを作成しました。ビューは、cdi イベントを使用して通信する 2 つのコントローラー Bean によってサポートされていました。プルーフオブコンセプトは jee6-container (glassfish 3.1.1) にデプロイされました。
部門の行をクリックするたびに、ajax-Listener が cdi-Event を起動して、detail-Controller を更新し、その代わりに詳細テーブルを更新するという考え方です。このパターンは、複数のディテール テーブルまたは複数のマスター/ディテール/ディテール レベルに拡張できます。
エンティティを編集するには、テーブルの各行にエディター ボタンを追加するなどして、エディター ダイアログを開くことをお勧めします。新しい詳細を追加するには、テーブルのフッターで add-Actions を使用し、新しいエンティティでエディター ダイアログを開きます。エディター ダイアログの「OK」で、新しいエンティティで cdi イベントを再度発生させ、依存する詳細テーブルを更新します。作業を保存するには、マスター エンティティを保存する単一の「コミット」ボタンを使用します。トレーニングでは、適切に定義されたエンティティで jpa を使用し、@OneToMany 関係で orphanRemoval=true 属性を使用して esp を使用しました。
ビュー (scott.xhtml):
<p:panel id="deptPanel" header="Departements">
<p:dataTable id="deptTable" var="dept" value="#{deptUiController.departements}"
selectionMode="single" rowKey="#{dept.id}">
<p:ajax event="rowSelect" listener="#{deptUiController.onRowSelect}" update="@form"/>
<p:column headerText="Name">
<h:outputText id="name" value="#{dept.dname}"/>
</p:column>
<p:column headerText="Location">
<h:outputText id="loc" value="#{dept.loc}"/>
</p:column>
<p:column headerText="# of Emps">
<h:outputText id="size" value="#{dept.emps.size()}"/>
</p:column>
</p:dataTable>
</p:panel>
<p:panel id="empPanel" header="Employees in departement #{deptUiController.currentDept.dname}">
<p:dataTable id="empTable" var="emp" value="#{empUiController.employees}">
<p:column headerText="Name">
<h:outputText id="name" value="#{emp.ename}"/>
</p:column>
<p:column headerText="Job">
<h:outputText id="job" value="#{emp.job}"/>
</p:column>
<p:column headerText="Hiredate">
<h:outputFormat id="hiredate" value="{0,date,dd.MM.yyyy}">
<f:param value="#{emp.hiredate}"/>
</h:outputFormat>
</p:column>
</p:dataTable>
</p:panel>
マスターコントローラー:
@Named
@SessionScoped
public class DeptUiController implements Serializable {
private boolean initialized = false;
@EJB
private ScottCRUD crudEJB;
private List<Departement> departements;
private Departement currentDept;
public void populateData() {
if ( !initialized ) {
departements = crudEJB.findAllDepartements();
currentDept = departements.isEmpty() ? null : departements.get(0);
initialized = true;
fireDeptChange();
}
}
@Inject
private Event<Departement> deptChangeEvt;
private void fireDeptChange() {
deptChangeEvt.fire( currentDept );
}
public void onRowSelect(SelectEvent event) {
currentDept = (Departement) event.getObject();
fireDeptChange();
}
... getter, setter, more actions...
}
詳細コントローラー
@Named
@SessionScoped
public class EmpUiController implements Serializable {
private List<Employee> employees;
private Employee currentEmp;
private void populateData(Departement master) {
if ( master==null ) {
employees = Collections.emptyList();
} else {
employees = master.getEmps();
}
currentEmp = employees.isEmpty() ? null : employees.get(0);
}
public void observeDeptChanged( @Observes Departement master ) {
populateData( master );
}
... getter, setter, more actions...
}