如何在 p:dialog 中显示 p:dataTable 当前行的详细信息并在保存后更新
How to show details of current row from p:dataTable in a p:dialog and update after save
我有一个 JSF 2 应用程序,它有两个页面,一个用于列出学生,另一个用于显示给定学生的详细信息。列表页面在学生 table 的每一行中都有一个 link 到详细信息页面,单击时会在浏览器中打开一个新选项卡以显示这些详细信息。
现在要求更改为不再在新选项卡中显示详细信息,而是在列表页面的模式对话框中显示详细信息。
我的想法是简单地将详细信息页面内容嵌入模态对话框中,这样列表页面就不会变得太大而难以维护。下面开始我的疑惑。经过一些研究,我将列表每一行中的 link 更改为以下按钮:
<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
的 属性 以及与传递的 id 相对应的 Student
实例)但它永远不会被击中。
经过一段时间的思考,我开始明白为什么它不起作用。传递给详情页的参数是student.id
,但是student
是<p:datatable/>
中显示所有学生的var
的名字,所以student
在 <p:datatable/>
.
之外的 <p:dialog/>
中无效
所以,我需要的是一种使用给定行中相应学生的 ID 显示对话框的方法。理想情况下,我希望在此处调用 ajax,以便仅在需要时加载详细信息。
有什么想法吗?
该按钮应该是一个 ajax 按钮,它在 bean 中设置当前迭代的实体,然后更新对话框的内容,最后显示它。该对话框应该仅引用 bean 中的该实体并在保存时更新列表和 table。将对话框放在主窗体之外并且它有自己的窗体是非常重要的。
这是一个启动示例:
<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();
}
另请参阅:
- Creating master-detail pages for entities, how to link them and which bean scope to choose
- Keep p:dialog open when a validation error occurs after submit
- Difference between rendered and visible attributes of <p:dialog>
- How to display dialog only on complete of a successful form submit
我有一个 JSF 2 应用程序,它有两个页面,一个用于列出学生,另一个用于显示给定学生的详细信息。列表页面在学生 table 的每一行中都有一个 link 到详细信息页面,单击时会在浏览器中打开一个新选项卡以显示这些详细信息。
现在要求更改为不再在新选项卡中显示详细信息,而是在列表页面的模式对话框中显示详细信息。
我的想法是简单地将详细信息页面内容嵌入模态对话框中,这样列表页面就不会变得太大而难以维护。下面开始我的疑惑。经过一些研究,我将列表每一行中的 link 更改为以下按钮:
<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
的 属性 以及与传递的 id 相对应的 Student
实例)但它永远不会被击中。
经过一段时间的思考,我开始明白为什么它不起作用。传递给详情页的参数是student.id
,但是student
是<p:datatable/>
中显示所有学生的var
的名字,所以student
在 <p:datatable/>
.
<p:dialog/>
中无效
所以,我需要的是一种使用给定行中相应学生的 ID 显示对话框的方法。理想情况下,我希望在此处调用 ajax,以便仅在需要时加载详细信息。
有什么想法吗?
该按钮应该是一个 ajax 按钮,它在 bean 中设置当前迭代的实体,然后更新对话框的内容,最后显示它。该对话框应该仅引用 bean 中的该实体并在保存时更新列表和 table。将对话框放在主窗体之外并且它有自己的窗体是非常重要的。
这是一个启动示例:
<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();
}
另请参阅:
- Creating master-detail pages for entities, how to link them and which bean scope to choose
- Keep p:dialog open when a validation error occurs after submit
- Difference between rendered and visible attributes of <p:dialog>
- How to display dialog only on complete of a successful form submit