0

我在 JSF 中观察到以下行为:

使用“immediate=true”通过 AjaxBehaviour 触发的 UIInput 组件不会在 APPLY_REQUEST 中执行验证器,但始终在由 UIInput 本身确定的阶段中执行。这意味着 AjaxBehaviour 'immediate' 属性对何时处理组件的验证器没有影响。IMO 不是 AjaxBehaviour 的描述中所说的:

immediate 属性指示用户输入是在应用程序生命周期的早期还是之后处理。如果该属性设置为 true,则从此组件生成的事件在 Apply Request Values 阶段广播。否则,事件将在调用应用程序阶段广播。

阅读地点:Oracle 教程

即使在 AjaxBehaviour.isImmediate(component,behaviour) 中考虑,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");
}
}

在该示例中,验证器将不会在 APPLY_REQUEST 中执行,直到 SelectBoolCheckBox 也为 'immediate=true'。更糟糕的是,组件的立即数,即使是默认值,也总是获胜。这使得 AjaxBehaviour 直接属性完全没有价值。

任何人都可以和我解释或复制或咕哝吗?

4

0 回答 0