试图了解immediate =“true”时跳过的input
就在我以为我已经理解了立即… *叹*
考虑下面的JSF页面:
<h:inputText value="#{testBean.text}" required="true" /> <h:commandButton actionListener="#{testBean.doFoo}" value="Do Foo" /> <h:commandButton immediate="true" actionListener="#{testBean.doBar}" value="Do Bar" /><br /> <h:outputText value="#{testBean.didSomething}" />
而这个支持豆:
public class TestBean { private String didSomething = "Nothing done yet"; // + getter public void doFoo() { didSomething = "Did foo!"; } public void doBar() { didSomething = "Did bar!"; }
从我所读到的关于立即我会期望以下:
-
在尝试执行foo而不为input字段提供值时,操作从不执行,因为在
processValidationsPhase
期间发生错误,导致页面在此阶段之后直接重新呈现,并显示错误消息。didSomething
的价值保持不变。 (这按预期工作) -
当试图在没有为input字段提供值的情况下进行操作时,由于immediate属性,在
applyRequestValuesPhase
期间执行操作。 variablesdidSomething
被改变。 (这按预期工作)
接下来会发生什么, 这个描述指出:
“null返回值(作为操作方法的结果)导致处理继续正常,即非直接组件被validation,然后执行update-model(如果没有发生validation错误)。对于返回void的操作侦听器方法,有必要调用facesContext.renderResponse();如果不需要正常stream。
从这我有这样的想法,处理继续正常(因为我的行动方法既不返回结果也不强制renderResponse()
),导致相同的validation错误。 唯一的区别是它会在设置didSomething
之后发生。 但是,这不会发生。 相反,感觉网站仍然会跳过所有剩余的阶段,input字段没有被触摸。 它重新呈现没有错误信息。
有人能向我解释我的理解是如何工作的吗?
在button上immediate="true"
情况下,动作实际上在应用请求值阶段被调用,并且所有其余阶段被跳过。 这也是该属性的唯一要点:在应用请求值阶段,立即处理(解码,validation,更新和调用)组件。
所有不 immediate="true"
都被忽略。 只有immediate="true"
的input也被处理,但这也发生在应用请求值阶段。 为什么如果在应用请求值阶段已经发生了所有的事情,剩余的阶段呢?
在debuggingJSF生命周期文章中,您可以find以下摘要,其中应该指出何时(不)使用immediate"true"
:
好的,我应该什么时候使用即时属性?
如果还不完全清楚的话,下面是一个总结,并附有真实世界使用的例子,
如果仅在
UIInput
设置,则过程validation阶段将发生在应用请求值阶段。 使用这个优先考虑有问题的UIInput
组件的validation。 当其中任何一个validation/转换失败时,非即时组件将不会被validation/转换。如果仅在
UICommand
设置,则应用请求值阶段,直到更新模型值阶段将被跳过的任何UIInput
组件。 使用这个来跳过表单的整个处理。 例如“取消”或“返回”button。如果同时在
UIInput
和UICommand
组件中设置,那么应用请求值阶段,直到更新模型值阶段将被跳过的任何UIInput
组件没有这个属性设置。 使用它可以跳过对整个表单的处理,期望某些字段(立即)。 例如login表单中的“忘记密码”button,其中包含必需但不是即时的密码字段。
也可以看看:
- 为什么“直接”属性添加到EditableValueHolders?