26

就在我以为我立刻明白了……*叹息*

考虑以下 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}" />

而这个支持bean:

public class TestBean {
   private String didSomething = "Nothing done yet";
   // + getter

public void doFoo() {
    didSomething = "Did foo!";        
}

public void doBar() {
    didSomething = "Did bar!";        
}

从我读到的关于立即的所有内容中,我期望以下内容:

  • 当尝试在没有为输入字段提供值的情况下执行 foo 时,该操作永远不会执行,因为在processValidationsPhase发生错误期间,导致在此阶段之后直接重新渲染页面并显示错误消息。的值didSomething保持不变。(这按预期工作)

  • 当尝试在不为输入字段提供值的情况下执行 bar 时,applyRequestValuesPhase由于 immediate 属性,该操作将在 during 期间执行。变量didSomething已更改。(这按预期工作)

关于接下来会发生什么,此描述指出:

“空返回值(作为操作方法的结果)导致处理正常继续,即验证非立即组件然后执行更新模型(如果没有发生验证错误)。对于返回 void 的操作侦听器方法,如果不需要正常流程,则有必要调用 facesContext.renderResponse();。”

由此我认为处理会继续正常进行(因为我的操作方法既不返回结果也不返回 force renderResponse()),从而导致相同的验证错误。唯一的区别是它发生设置之后didSomething但是,这不会发生。相反,感觉网站仍然跳过了所有剩余的阶段,没有触摸输入字段。它重新渲染而没有错误消息。

有人可以向我解释我对它是如何工作的理解有问题吗?

4

1 回答 1

45

使用immediate="true"按钮,在应用请求值阶段确实会调用该操作,并跳过所有剩余阶段。这也是该属性的唯一要点:在应用请求值阶段立即处理(解码、验证、更新和调用)组件。

无论如何,所有没有的输入都会immediate="true"被忽略。只有确实有的输入immediate="true"也会被处理,但这也发生在应用请求值阶段。如果在应用请求值阶段已经发生了一切,为什么还要调用剩余的阶段?

Debug JSF 生命周期文章中,您可以找到以下摘要,该摘要应该启发何时(不)使用immediate"true"

好的,我什么时候应该使用 immediate 属性?

如果还不完全清楚,这里有一个总结,其中包含可能有益的真实世界使用示例:

  • 如果UIInput仅在 (s) 中设置,则流程验证阶段将改为在应用请求值阶段进行。使用它来优先验证有UIInput问题的组件。当其中任何一个的验证/转换失败时,非即时组件将不会被验证/转换。

  • 如果UICommand仅设置,则任何组件都将跳过应用请求值阶段直到更新模型值阶段UIInput。使用它跳过表单的整个处理过程。例如“取消”或“返回”按钮。

  • 如果在UIInput和组件中都设置了,则对于没有设置此属性UICommand的任何组件,将跳过应用请求值阶段直到更新模型值阶段。UIInput使用它来跳过对某些字段的整个表单的处理(立即)。例如,登录表单中的“忘记密码”按钮带有必填但非即时的密码字段。

也可以看看:

于 2012-10-18T18:19:48.670 回答