试图了解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。

  • 如果同时在UIInputUICommand组件中设置,那么应用请求值阶段,直到更新模型值阶段将被跳过的任何UIInput组件没有这个属性设置。 使用它可以跳过对整个表单的处理,期望某些字段(立即)。 例如login表单中的“忘记密码”button,其中包含必需但不是即时的密码字段。

也可以看看:

  • 为什么“直接”属性添加到EditableValueHolders?
Interesting Posts