【问题标题】:JSF Reset a property of ViewScoped bean back to initial value after renderJSF 在渲染后将 ViewScoped bean 的属性重置为初始值
【发布时间】: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


【解决方案1】:

您没有添加 primefaces 标签,但根据您的代码,我看到您正在使用 Primefaces。假设您的methodA() 是从例如p:commandButton 调用的。我建议首先创建 primefaces 远程命令:

<p:remoteCommand name="resetRenderLocationTable">
  <f:setPropertyActionListener value="#{false}" target="#{loc.renderLocationTable}"/>
</p:remoteCommand>

这将创建名为 resetRenderLocationTable 的 JavaScript 函数,其调用将生成 AJAX 请求,该请求会将 renderLocationTable 属性设置为 false。现在只需在oncomplete commandButton(或任何其他 AJAX 源)中添加对该函数的调用:

<p:commandButton action="#{loc.methodA()}" update="myDatatable" oncomplete="resetRenderLocationTable()"/>

在下一个请求中,您不必担心重置此属性,只需更新您的数据表。

【讨论】:

  • 这听起来是个好主意!我以前从未听说过“p:remoteCommand”(而且我已经使用 Primefaces 很长时间了)。我会尝试并告诉你。回复较晚,抱歉;直到今天(拉斯维加斯),我整个星期都在度假。
猜你喜欢
  • 2014-06-21
  • 2013-01-06
  • 1970-01-01
  • 2013-11-20
  • 2011-09-09
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多