2009年1月17日星期六

JSF_017:深刻理解immediate=true的含义

在实际使用中,我发现自己对immediate=true的了解仅仅局限在可以“跳过验证”环节,其实immediate=true还有很多别的意义,对应的使用场景也不同,下面就以实验的方式总结一下。

1. immediate=true的适用场景
(1)点击某个命令组件后直接导航到下一页面,不再验证当前页面的输入数据,不再处理值变事件等等环节。最典型的就是“取消”按钮。
(2)点击某个命令组件后直接调用组件上的action事件,不再验证当前页面的输入数据,不再处理值变事件等等环节。
(3)当某个输入组件验证出错了,不再验证其它输入组件,防止一次弹出所有的出错信息。

2. immediate=true是如何影响生命周期的?
我们知道JSF页面生命周期分为6个阶段,详细说明请参考《JSF 的生命周期》。
很多开发者常常以为:只要把组件的immediate=true,那么就会跳过"Process Validations" 阶段。
这其实是个误解,真相是:immediate=true时,只是该组件的所有事件处理将提前到"Apply Request Values "阶段。

3. 对输入组件来说,immediate=true意味着
组件将在"Apply Request Values "阶段进行验证,其它immediate=false的组件依然会在"Process Validations" 阶段验证。
如果immediate=true的组件验证不通过,那么将会直接进入"Render Response"阶段,不会再验证其它immediate=false的组件。
如果immediate=true的组件上还有值变事件,那么该事件也在"Apply Request Values "阶段触发执行,而不是原先默认的"Process Validations" 阶段。

4. 对命令组件来说,immediate=true意味着
组件上的ActionListener或action事件将在"Apply Request Values "阶段触发执行。
如果action事件返回一个非Null的String,那么将会根据导航规则直接导航到下一页面,即直接跳到"Render Response"阶段,不再经过中间的阶段,用户输入的数据将被丢弃。
取消按钮,就是我们最常见的例子。
如果action事件返回的String为Null,那么剩下的阶段继续按照原来的顺序执行。

5. 常见问题与解答
(1)immediate=true的输入组件,当用户输入数据后,在后台却得不到这个数据。
(2)immediate=true的命令组件,如何获得那些immediate=false的输入组件的值?
在Managed Bean中绑定到该输入组件,然后调用该组件的getSubmittedValue()方法,注意这个方法返回的是raw String,没有经过验证和转换。

说明:所有实验验证可以参考《使用PhaseListener观察JSF生命周期的各个阶段》。

参考文献:
1. http://wiki.apache.org/myfaces/How_The_Immediate_Attribute_Works。

没有评论: