1

我有一个 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,并且您发现自己在整个类中设置布尔标志为真或假,那么这种情况适用于您。

4

1 回答 1

0

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

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

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

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

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

于 2013-02-22T18:58:09.213 回答