【问题标题】:How to show details of current row from p:dataTable in a p:dialog and update after save如何在 p:dialog 中显示 p:dataTable 中当前行的详细信息并在保存后更新
【发布时间】:2015-10-22 17:59:15
【问题描述】:

我有一个 JSF 2 应用程序,它有两个页面,一个用于列出学生,一个用于显示给定学生的详细信息。列表页面在学生表的每一行中都有一个指向详细信息页面的链接,单击该链接会在浏览器中打开一个新选项卡以显示这些详细信息。

现在要求更改为不再在新选项卡中显示详细信息,而是在列表页面的模式对话框中。

我的想法是简单地将详细信息页面内容嵌入模式对话框中,这样列表页面就不会变得太大且难以维护。这里开始我的疑惑。经过一番研究,我将列表每一行中的链接更改为以下按钮:

<p:commandButton value="Details" type="button"
                 onclick="PF('dialog-details').show()">
</p:commandButton>

对话框声明如下:

<p:dialog widgetVar="dialog-details" header="Details" modal="true" width="95%">
    <ui:include src="student_details.xhtml">
        <ui:param name="id" value="#{student.id}"/>
    </ui:include>
</p:dialog>

最后,详情页变成了这样:

<ui:composition
    xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">

    <f:metadata>
        <f:viewParam name="id" value="#{studentBean.id}" />
    </f:metadata>

    <h1 class="title ui-widget-header ui-corner-all">Details of #{studentBean.bean.name} / #{studentBean.bean.number}</h1>
</ui:composition>                       

当我单击按钮时,对话框真正显示,内容是详细信息页面。我在对话框中看到以下内容:

Details of  / 

完全没有错误,但应该显示的数据却没有。在StudentBean.setId() 中设置了一个断点(此方法加载了一个名为bean 的属性,其中Student 实例对应于传递的id)但它永远不会被命中。

经过一段时间的思考,我开始明白为什么它不起作用了。传递给详细信息页面的参数是student.id,但student是在显示所有学生的&lt;p:datatable/&gt;中用作var的名称,因此student在外部&lt;p:dialog/&gt;中无效&lt;p:datatable/&gt;

所以,我需要一种使用给定行中相应学生的 id 来显示对话框的方法。理想情况下,我希望在此处调用 ajax,因此只有在需要时才会加载详细信息。

有什么想法吗?

【问题讨论】:

  • 我会研究view标签,但我没有在以前版本的详细信息页面中使用它,当它在不同的浏览器选项卡中显示时可以正常工作。
  • @BalusC:感谢您的提示,但对我没有帮助。我没有添加有关我的问题的一些细节:我的列表页面是一个组合,并使用一个实际上具有&lt;f:view/&gt; 标记的模板,因此该对话框确实是&lt;f:view/&gt; 的子项,正如帖子所告知的那样。无论如何,我非常感谢您尝试帮助我!

标签: jsf primefaces datatable dialog master-detail


【解决方案1】:

按钮应该是一个ajax按钮,它在bean中设置当前迭代的实体,然后更新对话框的内容,最后显示出来。对话框应该只引用 bean 中的实体并在保存时更新列表和表。对话框放置在主窗体之外并且有自己的窗体非常重要。

这是一个启动示例:

<h:form id="master">
    <p:dataTable value="#{bean.entities}" var="entity">
        <p:column>#{entity.property1}</p:column>
        <p:column>#{entity.property2}</p:column>
        <p:column>#{entity.property3}</p:column>
        ...
        <p:column>
            <p:commandButton value="View" action="#{bean.setEntity(entity)}" 
                update=":detail" oncomplete="PF('detail').show()" />
        </p:column>
    </p:dataTable>
</h:form>

<p:dialog id="detail" widgetVar="detail">
    <h:form>
        <p:inputText value="#{bean.entity.property1}" />
        <p:inputText value="#{bean.entity.property2}" />
        <p:inputText value="#{bean.entity.property3}" />
        ...
        <p:button value="Close" onclick="PF('detail').hide(); return false" />
        <p:commandButton value="Save" action="#{bean.save}" 
            update=":master" oncomplete="if(!args.validationFailed) PF('detail').hide()" />
    </h:form>
</p:dialog>

@ViewScoped bean 中使用这个:

private List<Entity> entities; // +getter
private Entity entity; // +getter+setter

@EJB
private EntityService entityService;

@PostConstruct
public void load() {
    entities = entityService.list();
    entity = null;
}

public void save() {
    entityService.save(entity);
    load();
}

另见:

【讨论】:

  • @Balus:太好了!您的回答对我来说非常有效,除了我必须将实体 ID 传递给将包含的其他页面的部分。似乎参数根本没有进入详细信息视图。
  • @Alex:我不了解功能要求。请说清楚。您的意思是要让对话框中的&lt;h:link&gt; 指向另一个页面,并且您需要将#{entity.id} 作为&lt;f:param&gt; 传递吗?
  • @Balus:这基本上是你所理解的,但是要显示的细节非常广泛,我已经在另一个页面中完成了它(另一个 XHTML 文件,记住当前的实现在另一个页面中显示了这些细节浏览器选项卡)。所以,我想做的是在对话框中显示详细信息页面内容。
  • 然后将原始页面拆分为您可以通过&lt;ui:include&gt; 包含在对话框中的内容,或者使用 primefaces 对话框框架。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
相关资源
最近更新 更多