我有一个 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
}
}
}
一旦调用 methodA() 并满足某些条件,则应呈现该表;这很好用。但是,问题在于,对于每一个被调用的其他 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,然后“回发”调用会将标志重置为 false……完美。但是,显然没有办法用 JSF 开箱即用地做到这一点。
那么,有人有解决这个问题的方法吗?
谢谢!
顺便说一句,这种情况的发生可能比你想象的要多得多。任何时候,只要您有一个使用 ActionListener 的带有多个 commandButtons 的表单,那么这种情况就可能发生在您身上。如果您曾经有一个 JSF ManagedBean,并且您发现自己在整个类中设置布尔标志为真或假,那么这种情况适用于您。