尝试理解立即=“真实”跳过输入,而不应该

时间:2012-10-18 17:53:01

标签: jsf commandbutton immediate-attribute

就在我以为我立刻明白了...... *叹气*

考虑以下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时,由于immediate属性,该操作在applyRequestValuesPhase期间执行。变量didSomething已更改。 (这可以按预期工作)

接下来会发生什么,this description声明:

  

“null返回值(作为action方法的结果)导致处理继续正常进行,即验证非直接组件然后执行update-model(如果没有发生验证错误)。对于动作侦听器方法返回void,有必要调用facesContext.renderResponse();如果不需要正常流量。“

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

有人可以向我解释我对其工作原理的理解是错误的吗?

1 个答案:

答案 0 :(得分:36)

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

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

Debug JSF lifecycle文章中,您可以找到以下摘要,该摘要应该启示何时(不)使用immediate"true"

  

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

     

如果还不完全清楚,这里有一个摘要,当它们可能有益时,可以使用真实世界的用例:

     
      
  • 如果仅在UIInput(s)中设置,则过程验证阶段将在申请请求值阶段进行。使用此选项可以优先验证相关UIInput组件的验证。当其中任何一个验证/转换失败时,将不会验证/转换非直接组件。

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

  •   
  • 如果同时在UIInputUICommand组件中设置,则应用请求值阶段直到更新模型值将跳过任何UIInput组件的阶段没有设置此属性。使用此选项可以跳过对某些字段(即时)的整个表单的处理。例如。登录表单中的“忘记密码”按钮,其中包含必填但非直接的密码字段。

  •   

另见: