jsf - JSF/PrimeFaces 中的单页主从

标签 jsf jpa primefaces master-detail

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

5年前关闭。




Improve this question




我很想知道有哪些好的实现模式 单页主从 View 中的 JSF-PrimeFaces/JPA 堆。网络上的大部分 Material 和教程似乎都只讨论每个 View 模式中相当琐碎的一张表。

但我对拥有 之类的东西很感兴趣。客户订购 数据库中的表和一个 xhtml 您可以在上半部分查看客户(例如,作为 p:datatable ),在下半部分查看当前选定客户的订单(再次作为 p:datatable ) )。我不清楚如何最好地组织 JSF/PrimeFaces/backing beans 和 Facades/entities/JPA 代码,以在最大程度代码重用的情况下以普遍适用的方式实现上述目标。例如。

  • 我应该为整个 定义一个支持 bean xhtml View 还是两个支持 bean,一个用于 View 的每个组件(主/细节)?
  • 模式是否可以推广到多个明细表(在同一级别)?。例如。看看客户上半部分的表格和下半部分的选项卡式 View ,由 的两个 View 组成订购 付款 分别是明细表(都与表 CUSTOMER
  • 有 N-1 关系)
  • 模式是否可以推广到多个详细级别(例如,在同一页面上查看 CUSTOMER INVOICE INVOICE67LINE 表.
  • 提议的模式也可以轻松适应修改。例如。使用可编辑的数据表,您可以使用提交更改按钮一次性更改客户详细信息并删除订单并完成两项更改。
  • 最佳答案

    对于最近的培训类(class),我们构建了以下 proofOfConcept。我们创建了一个包含两个表的单一 View ,一个主(部门)表和一个详细(员工)表。该 View 由两个使用 cdi 事件进行通信的 Controller bean 支持。 proofOfConcept 被部署到 jee6 容器(glassfish 3.1.1)。

    这个想法是每当您单击部门行时,ajax-Listener 会触发一个 cdi-Event 更新 detail-Controller 并作为返回更新详细信息表。这种模式可以扩展到多个明细表或多个主-明细-明细级别。

    为了编辑您的实体,我建议打开一个编辑器对话框,例如在表格的每一行中添加一个编辑器按钮。要添加新的详细信息,请使用表页脚中的 add-Actions 并使用新实体打开编辑器对话框。在编辑器对话框中的“确定”时,您再次使用新实体触发 cdi 事件以更新依赖的详细信息表。要保存您的工作,请使用单个“提交”按钮,它保存主实体。在训练中,我们将 jpa 与正确定义的实体一起使用,尤其是在 @OneToMany 关系中使用 orphanRemoval=true 属性。

    View (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>
    

    主 Controller :
    @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...
    
    }
    

    细节 Controller
    @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...
    
    }
    

    关于jsf - JSF/PrimeFaces 中的单页主从,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13031885/

    相关文章:

    java - 如何使用 JPA 和 Hibernate 映射集合的最新子项

    Jsf+Primefaces 响应式设计

    java - 用于基于表单的身份验证的 Tomcat 7 领域配置

    jquery - 如何存储请求 "offline"以便稍后执行?

    jsf - 调用 f :viewAction conditionally based on f:viewParam

    每个属性的 JSF 验证

    maven - 由于 REPO 网址被阻止,无法导入 Primefaces 依赖项

    java - 为什么这个表格内嵌编辑器不起作用?

    Spring-JPA : updating parent Entity fails to persist new child Entities, 将它们解释为 Transient

    java - spring-data 带下划线的属性名称不可转义,如文档所述