0

我有一个包含两个子视图的 JSF 页面。根据执行哪个 commandButton,将呈现其中一个子视图。但是,如果其中一个子视图的验证失败,则错误消息仍然可见,并且在下一次呈现子视图时组件仍然无效。我的 bean 中有一个解决方法来删除消息,但组件仍然无效。有没有办法将组件设置为有效或仅为子视图创建新视图?

这是我对消息的解决方法:

Iterator messageIterator = FacesContext.getCurrentInstance().getMessages();
    while (messageIterator.hasNext()) 
    {
            messageIterator.remove();
    }
4

2 回答 2

1

这是因为当rendered为 false 时组件不显示,但它仍然在视图的组件树中。所以组件没有显示,但它的值和状态仍然存在。

有几种方法可以解决这个问题:

  • 使用 JSTL 标记,例如<c:if />(如果可能的话)而不是rendered. 仅当条件为真时,标签内的页面元素<c:if/>才会出现在树中。

  • 从一个子视图传递到另一个子视图时,不要进行回发。这有效地从头开始重新创建树。例如,执行 GET 而不是 POST。

  • 使视图无效,以便重新创建树。使该commandButton切换子视图immediate="true"并使添加此代码的视图无效:

public void clearComponentTree() {
    FacesContext context = FacesContext.getCurrentInstance();
    Application application = context.getApplication();
    ViewHandler viewHandler = application.getViewHandler();
    UIViewRoot viewRoot = viewHandler.createView(context, context.getViewRoot().getViewId());
    context.setViewRoot(viewRoot);
    context.renderResponse();
}
  • 直接操作组件树删除不需要的组件(与上面类似,但仅限于特定组件)。在这里,我假设我们要删除具有 id 的子视图下的所有组件sub1(这immediate="true"也需要):
public void clearSubtree() {
    FacesContext context = FacesContext.getCurrentInstance();
    context.getViewRoot().findComponent(":sub1").getChildren().clear();
}

此链接提供了实现此目的的其他次要方法。

于 2012-10-17T18:35:52.227 回答
0

尝试使用 primefaces 扩展:resetInput重新建立输入的状态:

<p:commandButton value="Load Subview" action="#{bean.startSubview}" update="subview" process="@this" >
    <pe:resetInput for="subview"/>
</p:commandButton>
于 2012-11-08T00:53:57.273 回答