我有一个ViewScoped ManagedBean。这个bean有一个布尔属性,用于控制是否应该显示数据表。见下文:
<p:dataTable value="#{loc.locationRows}" var="obj" ... rendered="#{loc.renderLocationTable}">
<p:column>
...
</p:column>
...
</p:dataTable>
我的ManagedBean如下所示:
@ManagedBean(name = "loc")
@ViewScoped
public class LocationController implements Serializable {
private boolean renderLocationTable = false;
// JSF ActionListener.
public void methodA() {
if(someCondition) {
renderLocationTable = true; // this is the only time we should render location table
}
}
}
只要方法A()被调用并且满足某个条件,就应该呈现该表;这很好用。但是,问题是,对于每一个被调用的JSF ActionListener方法,我都必须显式地将呈现的布尔值设置回false。见下文:
@ManagedBean(name = "loc")
@ViewScoped
public class LocationController implements Serializable {
private boolean renderLocationTable = false;
// JSF ActionListener.
public void methodA() {
if(someCondition) {
renderLocationTable = true; // this is the only time we should render location table
}
}
// JSF ActionListener.
public void methodB() {
renderLocationTable = false;
}
// JSF ActionListener.
public void methodC() {
renderLocationTable = false;
}
}
我给出了一个非常小的ManagedBean和XHTML文件的片段。事实上,这些文件是巨大的,许多事情都与其他几个布尔"渲染"标志一起发生。保持这些标志的准确性变得越来越困难。此外,每个ActionListener方法现在都必须了解所有布尔标志,即使它们与手头的业务无关。
这就是我希望能够做到的:
<f:event type="postRenderView" listener="#{loc.resetRenderLocationTable}" />
<p:dataTable value="#{loc.locationRows}" var="obj" ... rendered="#{loc.renderLocationTable}">
<p:column>
...
</p:column>
...
</p:dataTable>
然后,在ManagedBean中有一个方法:
public void resetRenderLocationTable(ComponentSystemEvent event) {
renderLocationTable = false;
}
这不是很好吗?不再玩重置布尔变量的游戏。没有更多的测试用例需要确保表不会在不应该显示的时候显示。当适当的JSF ActionListener方法将其设置为true时,可以将呈现的标志设置为true,然后"post-back"调用将标志重置回false。。。完美的但是,显然JSF没有办法开箱即用。
那么,有人能解决这个问题吗?
谢谢!
顺便说一句,这种情况发生的次数可能比你想象的要多得多。任何时候,只要你有一个使用ActionListeners的带有多个命令按钮的表单,这种情况都可能发生在你身上。如果您曾经使用过JSF ManagedBean,并且发现自己将布尔标志设置为true或false分散在类中,那么这种情况适用于您。
您没有添加primefaces标记,但根据您的代码,我看到您正在使用primefaces。A假设您的methodA()
是从调用的,例如p:commandButton
。我建议首先创建素数面远程命令:
<p:remoteCommand name="resetRenderLocationTable">
<f:setPropertyActionListener value="#{false}" target="#{loc.renderLocationTable}"/>
</p:remoteCommand>
这将创建名为resetRenderLocationTable
的JavaScript函数,该函数的调用将生成AJAX请求,该请求将renderLocationTable
属性设置为false
。现在只需在commandButton
(或任何其他AJAX源)的oncomplete
中添加对该函数的调用:
<p:commandButton action="#{loc.methodA()}" update="myDatatable" oncomplete="resetRenderLocationTable()"/>
在下一个请求中,您不必担心重置此属性,只需更新数据表即可。