我在JSF中观察到以下行为:
通过AjaxBehaviour使用'immediate = true'触发的UIInput组件没有在APPLY_REQUEST中执行验证器,但始终处于由UIInput本身确定的阶段。这意味着AjaxBehaviour'immediate'属性对处理组件验证器的时间没有影响。哪个是IMO,而不是AjaxBehaviour的描述:
immediate属性指示是在应用程序生命周期的早期还是稍后处理用户输入。如果该属性设置为true,则在“应用请求值”阶段期间广播从此组件生成的事件。否则,将在Invoke Applications阶段广播事件。
即使在AjaxBehaviour.isImmediate(组件,行为)中,JSF也会考虑让AjaxBehaviour比组件更重要
private boolean isImmediate(UIComponent component, AjaxBehavior ajaxBehavior) {
boolean immediate = false;
if(ajaxBehavior.isImmediateSet()) {
immediate = ajaxBehavior.isImmediate();
} else if(component instanceof EditableValueHolder) {
immediate = ((EditableValueHolder)component).isImmediate();
} else if(component instanceof ActionSource) {
immediate = ((ActionSource)component).isImmediate();
}
return immediate;
}
而在UIInput.processDecodes(context)中没有触发该阶段的验证,因为该组件不是“立即”..
public void processDecodes(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
// Skip processing if our rendered flag is false
if (!isRendered()) {
return;
}
super.processDecodes(context);
if (isImmediate()) {
executeValidate(context);
}
}
反正;重现我的情况:
A)JSF代码:
<h:selectBooleanCheckbox id="mandatory" value="#{currentQuestion.mandatory}" label="#{texts.mandatory_Question}" disabled="#{!bean.metadata.editable}" validator="mandatoryValidator" onchange="makeDirty()" immediate="false">
<f:ajax event="click" execute="@this" render="@this :mandatory-msg" immediate="true"/>
</h:selectBooleanCheckbox>
<h:outputLabel for="mandatory" value="#{texts.mandatory_Question}" styleClass="standard-label chkBox-label" />
<p:message for=":mandatory" id="mandatory-msg" showDetail="true" showSummary="true" />
B)自定义验证器:
@FacesValidator("mandatoryValidator")
public class MandatoryValidator implements Validator {
/** logger. */
private static final Logger LOG = Logger.getLogger(MandatoryValidator.class.getName());
/** {@inheritDoc} */
@Override
public final void validate(final FacesContext context, final UIComponent component, final Object value) {
if (FacesContext.getCurrentInstance().getCurrentPhaseId() == PhaseId.APPLY_REQUEST_VALUES) {
LOG.debug("apply phase");
}
if (FacesContext.getCurrentInstance().getCurrentPhaseId() == PhaseId.PROCESS_VALIDATIONS) {
LOG.debug("validation phase");
}
}
在该示例中,在SelectBoolCheckBox也是'immediate = true'之前,验证器不会在APPLY_REQUEST中执行。更糟糕的是,组件的即时性,即使是默认的,也总是获胜。这使得AjaxBehaviour直接属性完全没用。
任何人都可以向我解释,复制或咕噜声吗?