【发布时间】:2013-02-06 00:03:06
【问题描述】:
我有一个 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 文件的 sn-p。在现实中,这些文件很大,而且还有很多其他布尔“渲染”标志正在发生。保持这些标志的准确性变得越来越困难。此外,每个 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,并且发现自己将布尔标志设置为 true 或 false 分散在整个类中,那么这种情况适用于您。
【问题讨论】:
-
如果所有动作侦听器所做的只是重置该标志,那么您可以将各种组件的动作侦听器指向托管 bean 中的同一方法,不是吗?所以只有一个地方可以重置该值。
-
为什么不能将检查
someCondition的逻辑移到preRenderView事件监听器中?侦听器应在每次回发时切换变量的状态 -
其他 ActionListener 方法(如上所示的methodB() 和methodC())所做的远不止重置该标志。实际上,methodB() 和 methodC() 与该标志无关,只是如果它们不将该标志设置为 false,则数据表将在不应该显示的时候显示。
-
另外,preRenderView 无效的原因是,将 methodA() 想象为一个非常复杂且资源密集型的方法。每次回发发生时,PreRenderView 都会执行该代码。我的方法是,methodA() 只在需要时才被调用。
-
例如,当我说: if(someCondition) { renderLocationTable = true };确定“someCondition”所需的工作量很大。这就是为什么我只想在需要时执行该代码。
标签: jsf primefaces reset