我有一个包含两个 subview 的 JSF 页面。根据执行哪个命令按钮,将呈现 subview 之一。但是,如果其中一个 subview 的验证失败,错误消息将保持可见,并且组件在下次呈现 subview 时仍然无效。我的 bean 中有一个解决方法可以删除消息,但组件仍然无效。有没有办法将组件设置为有效或仅为 subview 创建新 View ?
这是我处理消息的方法:
Iterator messageIterator = FacesContext.getCurrentInstance().getMessages();
while (messageIterator.hasNext())
{
messageIterator.remove();
}
最佳答案
这是由于当 rendered
时造成的为 false 时,组件不会显示,但它仍然位于 View 的组件树中。因此该组件不会显示,但其值和状态仍然存在。
有几种方法可以解决这个问题:
使用 JSTL 标签,例如
<c:if />
(如果可能的话)而不是rendered
。<c:if/>
内的页面元素仅当条件为真时,标记才会出现在树中。从一个 subview 传递到另一个 subview 时不要进行回发。这有效地从头开始重新创建树。例如,执行 GET 而不是 POST。
使 View 无效,以便重新创建树。使
commandButton
切换 subviewimmediate="true"
并使 View 无效添加以下代码:
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
的 subview 下的所有组件(这也需要immediate="true"
):
public void clearSubtree() {
FacesContext context = FacesContext.getCurrentInstance();
context.getViewRoot().findComponent(":sub1").getChildren().clear();
}
this link提供了实现这一目标的其他小方法。
关于java - 如何让 subview 在每次渲染时创建一个新 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12939799/