试图理解立即=“真"不应该跳过输入 [英] Trying to understand immediate="true" skipping inputs when it shouldn't

查看:14
本文介绍了试图理解立即=“真"不应该跳过输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

就在我以为我已经明白了的时候...... *叹气*

考虑以下 JSF 页面:

<h:commandButton actionListener="#{testBean.doFoo}" value="Do Foo"/><h:commandButtonimmediate="true" actionListener="#{testBean.doBar}" value="Do Bar"/><br/><h:outputText value="#{testBean.didSomething}"/>

还有这个支持 bean:

公共类TestBean {private String didSomething = "什么都没做";//+ 获取器公共无效 doFoo() {didSomething = "Did foo!";}公共无效 doBar() {didSomething = "做了吧!";}

从我读到的所有关于即时的信息来看,我期望以下内容:

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

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

关于接下来会发生什么,这个描述指出:><块引用>

空返回值(作为 action 方法的结果)导致处理照常继续,即验证非即时组件,然后执行更新模型(如果没有发生验证错误).对于一个 action listener 方法,返回void,需要调用facesContext.renderResponse();如果不想要正常流程."

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

有人可以向我解释一下我对它的工作原理的理解有什么问题吗?

解决方案

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

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

调试 JSF 生命周期 文章中,您可以找到以下总结应该启发何时(不)使用immediatetrue":

<块引用>

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

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

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

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

  • 如果同时在 UIInputUICommand 组件中设置,应用请求值阶段直到更新模型值阶段将被跳过任何 未设置此属性的 UIInput 组件.使用它可以跳过对某些字段(立即)的整个表单的处理.例如.忘记密码"带有必填但非即时密码字段的登录表单中的按钮.

另见:

Just when I thought I had understood immediate... *sigh*

Consider the following JSF page:

<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}" />

And this backing bean:

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

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

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

From all I read about immediate I would expect the following:

  • When trying to do foo while not providing a value for the input field, the action is never executed because during processValidationsPhase an error occurs, resulting in the page to be re-rendered directly after this phase with an error message. The value of the didSomething remains unchanged. (This works as expected)

  • When trying to do bar while not providing a value for the input field, the action is executed during applyRequestValuesPhase because of the immediate attribute. The variable didSomething is changed. (This works as expected)

On what happens next, this description states:

"A null return value (as outcome of the action method) causes processing to continue as normal, ie non-immediate components are validated then update-model is executed (if no validation errors occurred). For an action listener method that returns void, it is necessary to call facesContext.renderResponse(); if the normal flow is not desired."

From this I had the idea that processing continues as normal (as my action method does neither return an outcome nor force renderResponse()), resulting in the same validation error. Only difference would be that it occurs after setting didSomething. However, this does not happen. Instead, it feels like the site still skips all remaining phases, with the input field not being touched. It re-renders without error message.

Can someone explain to me where my understanding of how this works is amiss?

解决方案

With immediate="true" on the button, the action is indeed invoked during apply request values phase and all the remaining phases are skipped. That's also the sole point of this attribute: process (decode, validate, update and invoke) the component immediately during apply request values phase.

All inputs which do not have immediate="true" are ignored anyway. Only inputs which do have immediate="true" are also processed, but this happens also during apply request values phase. Why should the remaining phases be invoked if everything has already taken place in the apply request values phase?

In the Debug JSF lifecycle article you can find the following summary which should enlighten when to (not) use the immediate"true":

Okay, when should I use the immediate attribute?

If it isn't entirely clear yet, here's a summary, complete with real world use examples when they may be beneficial:

  • If set in UIInput(s) only, the process validations phase will be taken place in apply request values phase instead. Use this to prioritize validation for the UIInput component(s) in question. When validation/conversion fails for any of them, the non-immediate components won't be validated/converted.

  • If set in UICommand only, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s). Use this to skip the entire processing of the form. E.g. "Cancel" or "Back" button.

  • If set in both UIInput and UICommand components, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s) which does not have this attribute set. Use this to skip the processing of the entire form expect for certain fields (with immediate). E.g. "Password forgotten" button in a login form with a required but non-immediate password field.

See also:

这篇关于试图理解立即=“真"不应该跳过输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆