何时在UIComponent上调用setValue和setSubmittedValue?

时间:2013-03-28 20:04:04

标签: jsf components lifecycle

如果我正确地将BalusC伟大的2006年帖子http://balusc.blogspot.ch/2006/09/debug-jsf-lifecycle.html中包含的信息与Optimus Prime甚至更早的帖子http://cagataycivici.wordpress.com/2005/12/28/jsf_component_s_value_local/合并,我得到以下信息:

我的理解:

  1. 在APPLY_REQUEST_VALUES阶段,
    • 将输入值设置为UI组件的submittedValue属性(例如inputComponent。 setSubmittedValue (“test”))。
  2. 在PROCESS_VALIDATIONS阶段,
    • 从submittedValue属性中读取相同的值(可能是inputComponent。 getSubmittedValue ())并在必要时用于转换。
    • 如果转换成功或跳过,则结果将设置为组件的value属性(例如inputComponent。 setValue (“test”))。
    • 此外,立即再次删除submittedValue(例如inputComponent。 setSubmittedValue (null))
    • 从(转换)值中读取UI组件的value属性(可能是inputComponent。 getValue())并进行验证。
    • 验证后,读取支持bean / model的存储值(例如myBean。 getInputValue ()),并与新转换和验证的值进行比较。如果不同,将调用valueChangeListener方法。
  3. 在UPDATE_MODEL_VALUES阶段,
    • 新转换和验证的值最终存储在辅助bean的属性字段中(例如myBean。 setInputValue (“test”))。
  4. 问题:

    • 这是对的吗?
    • 是否缺少完全理解POST和保存输入值在支持bean之间的内容?
    • 在输入组件上使用immediate =“true”,我们只是将这些事件转移到APPLY_REQUEST_VALUES阶段,还是只更改事件的时间/顺序?

1 个答案:

答案 0 :(得分:4)

几乎正确。只有在转换验证成功时才会设置组件的本地值。之后,提交的值将设置为null。您可以在UIInput#validate()方法中以相当自我文档的方式找到验证阶段的整个过程(行号符合JSF 2.1 API):

934    public void validate(FacesContext context) {
935 
936         if (context == null) {
937             throw new NullPointerException();
938         }
939 
940         // Submitted value == null means "the component was not submitted
941         // at all".  
942         Object submittedValue = getSubmittedValue();
943         if (submittedValue == null) {
944             return;
945         }
946 
947         // If non-null, an instanceof String, and we're configured to treat
948         // zero-length Strings as null:
949         //   call setSubmittedValue(null)
950         if ((considerEmptyStringNull(context)
951              && submittedValue instanceof String 
952              && ((String) submittedValue).length() == 0)) {
953             setSubmittedValue(null);
954             submittedValue = null;
955         }
956 
957         Object newValue = null;
958 
959         try {
960             newValue = getConvertedValue(context, submittedValue);
961         }
962         catch (ConverterException ce) {
963             addConversionErrorMessage(context, ce);
964             setValid(false);
965         }
966 
967         validateValue(context, newValue);
968 
969         // If our value is valid, store the new value, erase the
970         // "submitted" value, and emit a ValueChangeEvent if appropriate
971         if (isValid()) {
972             Object previous = getValue();
973             setValue(newValue);
974             setSubmittedValue(null);
975             if (compareValues(previous, newValue)) {
976                 queueEvent(new ValueChangeEvent(this, previous, newValue));
977             }
978         }
979 
980     }

关于immediate组件上的UIInput属性,是的,这只是将验证转移到应用请求值阶段。另请参阅UIInput#processDecodes()UIInput#processValidators()的源代码,检查UIInput#isImmediate()