Jen*_*ens 6 java validation ajax jsf omnifaces
在我的基于JSF 2的应用程序中,我有一个包含(在其他UI组件中)一些复选框的表单.
在复选框上,我已经注册了在检查时触发的ajax请求.ajax请求实际上只会更新辅助bean中另一个复选框的值.因此,还将检查另一个复选框(当它被重新渲染时 - 因为它将在渲染响应阶段中从辅助bean获取更新的值).
这样可以正常工作,直到提交整个表单并发生验证错误.然后,ajax请求仍然可以工作并更改辅助bean上的值,但是在重新呈现更新的复选框的阶段,它的值不是从辅助bean中获取的,而是来自从ComponentStateHelper类中获取的缓存值.
据我所知,这用于JSF 2的新功能,只存储对组件树的部分更改.
我不明白的是:这与验证阶段有什么关系?StateHelper当验证发现错误时,为什么我的复选框的类中有缓存值?
这是一个已知问题,并在此答案中进行了深入解释。简而言之,这个问题是因为要渲染<f:ajax render>但不执行的无效组件<f:ajax execute>与原始提交的值一起保持无效状态。当JSF渲染输入组件时,JSF将首先检查提交的值是否不存在null,然后显示它,否则显示模型值。您基本上需要重置要渲染但不是由ajax执行的输入组件的提交值。
为了实现这一点,您可以使用基本上执行以下操作ActionListener:
UIViewRoot viewRoot = context.getViewRoot();
PartialViewContext partialViewContext = facesContext.getPartialViewContext();
Set<EditableValueHolder> inputs = new HashSet<EditableValueHolder>();
// First find all to be rendered inputs and add them to the set.
findAndAddEditableValueHolders(partialViewContext.getRenderIds(), inputs);
// Then find all executed inputs and remove them from the set.
findAndRemoveEditableValueHolders(partialViewContext.getExecuteIds(), inputs);
// The set now contains inputs which are to be rendered, but which are not been executed. Reset them.
for (EditableValueHolder input : inputs) {
input.resetValue();
}
Run Code Online (Sandbox Code Playgroud)
这已被报告为JSF 问题 1060,并且已在OmniFaces库中实现了完整且可重用的解决方案(此处ResetInputAjaxActionListener为源代码,此处展示了演示)。