我在 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 直接属性完全没有价值。
任何人都可以和我解释或复制或咕哝吗?