我对PrimeFaces和JSF很新,我找不到类似情况的主题。 我检查过我没有嵌套表格。好像我遇到了一些奇怪的行为 - 至少我不知道它为什么会这样做;)
假设我有一个列表。 “模块”类有一个列表。我的目的是在一个表中显示数据,很好地按模块和它下面的行中的元素分组。 看起来像subtable是我的愿望成真,但我发现它只是报告问题,所以它是不可选择的。不幸的是,我需要知道在模块上运行“删除”或“编辑”等操作的选择。 我尝试在subtable facet中放置一个按钮,其中actionlistener在backing bean中设置当前对象,然后打开一个对话框以提供进一步的操作(在所选模块上)。我首先想到它有效,但后来注意到按下相同的按钮,一个随机的模块对象被转移到了支持bean。
<p:dataTable id="displayModules" var="displayModuleBean"
value="#{displayModuleController.displayModuleBeans}"
emptyMessage="Es existieren keine Module für diese Kampagne.">
<p:row>
<p:column headerText="Vermarkter" />
<p:column headerText="Platzierung" />
<p:column headerText="Umfeld" />
<p:column headerText="Format(e)" />
<p:column headerText="Startdatum" />
<p:column headerText="Enddatum" />
<p:column headerText="Abrechnungsart" />
</p:row>
<p:subTable id="displayModuleElements" var="displayModuleElement"
value="#{displayModuleBean.moduleElements}"
sortBy="#{displayModuleBean.module.name}" sortOrder="descending">
<f:facet name="header" style="vertical-align: middle">
#{displayModuleBean.module.name}
<p:commandButton alt="Modul bearbeiten" icon="ui-icon-pencil"
style="float:right"
actionListener="#{displayModuleController.setSelectedDisplayModuleBean(displayModuleBean)}"
oncomplete="displayModuleEditDialog.show();"
update=":tabview:displayModulesDialogForm:editDisplayModules">
</p:commandButton>
</f:facet>
<p:column headerText="Vermarkter">
<h:outputText value="#{displayModuleElement.advertiserName}" />
</p:column>
</p:subTable>
</p:dataTable>
Backing Bean(DisplayModuleController,SessionScoped):
public void setSelectedDisplayModuleBean(ModuleBean selectedDisplayModuleBean)
{
this.selectedDisplayModuleBean = selectedDisplayModuleBean;
this.setSelectedDisplayModuleName(this.selectedDisplayModuleBean != null ? this.selectedDisplayModuleBean.getModule().getName()
: null);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Set selected ModuleBean: ",
this.selectedDisplayModuleBean != null ? this.selectedDisplayModuleBean.getModule().getName() : "keins");
}
我甚至在每个标签上尝试过使用Accordion Panel和Datatables的解决方法,但我结束了同样奇怪的行为。我还尝试在每一行中添加一个按钮来传输所选元素本身(而不是父模块),但它的工作方式完全相同。
我到底错过了什么?如果有人可以帮助我以正确的方式前进,那会很棒;)
我正在使用: PrimeFaces 4.0, MyFaces 2.1.13, Apache Tomcat 7.0.42
LG, ANI
答案 0 :(得分:1)
在表单提交期间解码操作方法时,将评估EL方法参数。在构建JSF组件树时,它们不进行评估,或者生成HTML输出。
为了确保正在评估正确的EL方法参数值,您需要在此特定情况下确保在处理表单提交期间#{displayModuleController.displayModuleBeans}
后面的模型完全相同就像在渲染(显示)表格时一样。
为了实现这一点,必须对支持bean进行视图作用,并且该模型的getter必须绝对没有任何业务逻辑。必须准备模型并填写一次性初始化/操作方法,例如@PostConstruct
,以防您想要“在页面加载时”或在操作(监听器)方法中填充它,以防您遇到喜欢事先在“提交时”填充它。
否则,模型可能会关闭,因为您首先排序,然后通过unnecessarily在getter方法中执行DB调用,从数据库重新加载模型,就像许多初学者一样。
作为一种完全不同的替代方案,如果您无法确保模型的完整性,从而冒着在显示表单和处理表单提交之间不兼容更改的风险,那么您可以使用<f:param>
传递静态参数。它将表示完全该值在播放表单期间(在呈现响应期间),而不是在处理表单提交期间。
E.g。
<p:commandButton ... actionListener="#{displayModuleController.setSelectedDisplayModuleBean}">
<f:param name="id" value="#{displayModuleBean.id}" />
</p:commandButton>
您可以通过<f:viewParam name="id">
,@ManagedProperty("#{param.id}")
或externalContext.getRequestParameterMap().get("id")
进行设置,然后根据ID DisplayModuleBean
转换回具体的find()
。另请参阅How can I pass selected row to commandLink inside dataTable?
答案 1 :(得分:0)
如果您正在处理实体您也可以将唯一ID作为参数传递给BackingBean,编写一个将ID作为参数的select方法,并将选定的Object设置为@WindowScoped
BackingBean的实例。然后你可以这样访问你的实例:
#{myBean.instance.propertyName}
通过这种方式,您可以确保使用正确的实例。