【问题标题】:Why this line [isLocalValueSet() ? getLocalValue(): ...] instead of [isLocalValueSet() ? getValue(): ...] in UIInput class?为什么这一行 [isLocalValueSet() ? getLocalValue(): ...] 而不是 [isLocalValueSet() ? getValue(): ...] 在 UIInput 类中?
【发布时间】:2016-04-27 12:00:18
【问题描述】:

我已经通过this,但答案对我来说不是很清楚。于是问,

对于UIInput 类的验证方法,我们有这个(只标记与问题相关的那些行)

public void validate(FacesContext context) {

     Object submittedValue = getSubmittedValue();           // LINE 958

     newValue = getConvertedValue(context, submittedValue); // LINE 976

     validateValue(context, newValue);                      // LINE 983

     if (isValid()) {                                       // LINE 987
            Object previous = getValue();
            setValue(newValue);                             // LINE 989
            setSubmittedValue(null);
     }
}

如果转换和验证都成功,则isValid() 返回true。

然后设置组件的 local 值 - setValue(newValue),由标志 setLocalValueSet(true) 指示

之后,submitted 值设置为 null - setSubmittedValue(null)

如果你看一下 UIInput 的 setValue(...) 方法的代码,它被覆盖了,

@Override
public void setValue(Object value) {
    super.setValue(value);
    // Mark the local value as set.
    setLocalValueSet(true);
}

所以从第 989 行开始,调用委托给上面的 setValue(...)。 如果你看看这个方法,

@Override
public Object getValue() {
    return isLocalValueSet() ? getLocalValue() : super.getValue();
}

如果本地值由 setValue(...) 设置,由标志 setLocalValueSet(true) 指示, 为什么这会返回 getLocalValue()? 我的意思是,

isLocalValueSet() ? getLocalValue() : ....

为什么没有

isLocalValueSet() ? getValue() : ....

如上所示,我的困惑在于getValue() 和getLocalValue() 方法。此外,在哪种情况下Object previous = getValue(); 将是not null?

【问题讨论】:

    标签: jsf input lifecycle


    【解决方案1】:

    如果本地值是由 setValue(...) 设置的,由标志 setLocalValueSet(true) 指示,为什么会返回 getLocalValue()?

    我认为阅读ValueHolder接口的javadoc很有帮助。

    Object getLocalValue()

    返回此 UIComponent 的本地值(如果有),不评估任何关联的 ValueExpression。

    Object getValue()

    获取此UIComponent 的值。如果验证失败,如FacesContext.isValidationFailed() 返回true 所示,始终返回本地值。否则,首先请查阅该组件的本地值属性。如果非null 则返回。如果是null,看看我们是否有一个ValueExpression 作为value 属性。如果是,则返回评估属性的结果,否则返回null。

    void setValue(Object value)

    设置此UIComponent 的值(如果有)。

    请注意我对“没有”的强调。

    换句话说,getLocalValue() 和 setValue() 形成了真正的 getter/setter 对,基本上是指组件自己的实例变量,而不是组件的 value 属性中指定的任何表达式后面的 bean 属性,例如 value="#{bean.value}"。

    getValue() 方法的实现方式是,当验证尚未失败且本地值为null 时,它会自动评估任何关联的ValueExpression。当(转换后的)提交值实际上是 null 并且组件仍在忙于处理验证阶段并且模型值尚未更新时,这是不可取的。

    简单地说,如果使用getValue() 而不是getLocalValue(),那么“用户删除(非必需)输入值”的情况将失败,因为getValue() 返回初始模型值。


    此外,在这种情况下 Object previous = getValue();不会为空?

    当模型中有初始值时。

    【讨论】:

    • 您在stackoverflow.com/questions/6642242/… 提到[当JSF 在验证阶段对特定输入组件的验证失败时,提交的值将保留在输入组件中。]即未设置本地值(即 validatemethod 中的 setValue(...) 不是 c/d)。然而,与上面的 getValue() 一样,如果验证失败,如 FC.isValidationFailed() 返回 true 所示,则始终返回本地值。如果验证失败,为什么返回本地值。
    • 当验证阶段由于任何地方的转换或验证错误而失败时,成功通过验证的组件将返回本地值,验证失败的组件将返回提交的值。
    • 但是 getValue() 的 javadoc 让我感到困惑。如果验证失败[这将针对特定组件],如 FacesContext.isValidationFailed() 返回 true 所示,始终返回本地值。他们没有说返回提交的值。
    • 提交的值通过getSubmittedValue()访问。请注意,这只发生在渲染响应阶段。
    • 验证方法为PROCESS VALIDATIONS PHASE中的c/d。提交的值在这里被访问- Object submitValue = getSubmittedValue();为了进一步解释,我提出了这个-stackoverflow.com/questions/36907050/…
    猜你喜欢
    • 2013-03-02
    • 2012-06-12
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多