如何让子视图在每次渲染时创建一个新视图

时间:2012-10-17 17:19:12

标签: java jsf primefaces

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

以下是我处理消息的方法:

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

2 个答案:

答案 0 :(得分:1)

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

有几种解决方法:

  • 使用<c:if />等JSTL代码(如果可能的话)代替rendered。仅当条件为真时,<c:if/>标记内的页面元素才会在树中。

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

  • 使视图无效,以便重新创建树。制作切换子视图commandButton的{​​{1}}并使添加此代码的视图无效:

immediate="true"
  • 直接操作组件树,删除不需要的组件(类似于上述内容,但仅限于特定组件)。在这里,我假设我们要删除ID为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(); } 的子视图下的所有组件(这也需要sub1):
immediate="true"

this link提供了实现此目标的其他小方法。

答案 1 :(得分:0)

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

<p:commandButton value="Load Subview" action="#{bean.startSubview}" update="subview" process="@this" >
    <pe:resetInput for="subview"/>
</p:commandButton>