我的页面上有两个输入组件。他们每个都有一个转换器(它是一个检查空值的转换器,比如JSF需要的一个,但由于某些原因我不能使用jsf,所以我自己创建了转换器。)
我还有ice:selectBooleanCheckbox
:
<ice:selectBooleanCheckbox
styleClass="graUserAppUserGroupAddChk"
value="#{userGroupTableNewRecordBean.addNewDomain}"
partialSubmit="true"
immediate="true"
valueChangeListener="#{userGroupTableNewRecordBean.addDomainListener}"></ice:selectBooleanCheckbox>
如你所见,我在其上添加了immediate=true
属性,因为当我选中此复选框时,我确实希望转换阶段被跳过但不起作用,转换器仍会显示警告。你知道为什么吗?
我还在此复选框上添加了一个valueChangeListener,并根据此引用直接调用了renderResponse:
So in the value changed listener method for the dropdown lists, just
从中调用renderResponse() FacesContext对象和验证 转换被绕过,你可以 仍然做你想做的事。
public void addDomainListener(final ValueChangeEvent valueChangeEvent) {
// skip validation
logger.info("listener calleddddddddddddd");
FacesContext.getCurrentInstance().renderResponse();
}
也许JSF大师可以提供帮助吗?
非常感谢...
更新:我知道解决方案是将复选框放在单独的表单中,但我买不起......
UPDATE 2 :我已经更正了一些关于侦听器的代码,所以现在点击时调用它但仍然转换器失败并且渲染响应阶段未完成 ..
更新3 :这不是一个问题......我试过h:selectBooleanCheckbox
并且它发生了同样的事情......
答案 0 :(得分:3)
整个问题以及这一切背后的功能要求都令人困惑。为什么使用转换器而不是验证器来验证输入?如果您似乎不关心转换/验证结果,为什么使用转换器/验证器?
如你所见,我将immediate = true属性放在其上,因为当我选中此复选框时,我确实希望跳过转换阶段,但它不起作用,转换器仍会显示警告。
将immediate="true"
放在输入组件上不会跳过转换/验证。它们只是将转换/验证转移到早期阶段(即它发生在应用请求值阶段而不是验证阶段)。您基本上需要从这些输入中删除immediate="true"
并将其放在命令链接/按钮上,以跳过这些输入的转换/验证。另请参阅Debug JSF lifecycle:
Okay, when should I use the immediate attribute?
如果还不完全清楚,这里有一个摘要,当它们可能有益时,可以使用真实世界的用例:
如果仅在
UIInput
(s)中设置,则过程验证阶段将在申请请求值阶段进行。使用此选项可以优先验证相关UIInput
组件的验证。当其中任何一个验证/转换失败时,将不会验证/转换非直接组件。如果仅在
UICommand
中设置,则应用请求值阶段直到更新模型值阶段将跳过任何UIInput
组件。使用此选项可跳过表单的整个处理过程。例如。 “取消”或“返回”按钮。如果同时在
UIInput
和UICommand
组件中设置,则应用请求值阶段直到更新模型值将跳过任何UIInput
组件的阶段没有设置此属性。使用此选项可以跳过对某些字段(即时)的整个表单的处理。例如。登录表单中的“忘记密码”按钮,其中包含必填但非直接的密码字段。
答案 1 :(得分:0)
终于解决了......
我在这里发布问题和解决方案的总结。
我的弹出窗口中有一个复选框。当我选择时,我想显示一些隐藏字段,但这不起作用,因为我在同一页面上还有两个必填字段,所以jsf PROCESS_VALIDATIONS阶段出现了......
我认为放immediate=true
会解决这个问题,但事实并非如此......
所以,在我的复选框的ValueChangeListener中,我必须手动跳过 jsf验证阶段:
public void addDomainListener(final ValueChangeEvent valueChangeEvent) {
// skip validation
final PhaseId phaseId = valueChangeEvent.getPhaseId();
final Boolean newValue = (Boolean) valueChangeEvent.getNewValue();
if (phaseId.equals(PhaseId.ANY_PHASE)) {
valueChangeEvent.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
valueChangeEvent.queue();
this.addNewDomain = newValue;
FacesContext.getCurrentInstance().renderResponse();
}
}