Initially immediate
flag was only intended for ActionSource
interface. But later on it was added to the EditableValueHolder
interface also. What was the reason for design decision ?
问题:
回答1:
It's to be used to prioritize validation on several EditableValueHolder
components in the same form.
Imagine a form containing input components with immediate="true"
as well as input components without this attribute. The immediate inputs will be validated during apply request values phase (which is one phase earlier than usual). The non-immediate inputs will be validated during validations phase (which is the usual phase). If validation fails for at least one of the immediate inputs, then the non-immediate inputs won't be converted/validated at all and thus won't generate any conversion/validation error messages. This is particularly useful in forms with complex validation rules where it doesn't make sense to validate component Y when validation for (immediate) component X has failed anyway.
When used in combination with immediate="true"
on a command button in the same form, this will cause all non-immediate inputs being completely skipped. A good real world example is a login form with 2 fields "username" and "password" with required="true"
and 2 buttons: "login" and "password forgotten". You could put immediate="true"
on the "username" field and the "password forgotten" button to skip the required="true"
check on the password field.
In the dark JSF 1.x ages, the immediate="true"
was also often (ab)used as a hack in combination with valueChangeListener
and FacesContext#renderResponse()
, more than often in cascading dropdown lists. Long story short, here's an old blog article on that. To the point, it enables developers to execute a backing bean method on change of a <h:selectOneMenu>
without that all other inputs in the same form are been validated. But these days, with the ajax awesomeness, this hack is unnecessary. You can find a concretre example of this case at the bottom of our <h:selectOneMenu>
wiki page.
These days, the immediate="true"
is still often (ab)used in order to have a specific button which completely bypasses all other inputs, such as a logout button in a "God-form" antipattern (whereby everything is been thrown together in a huge <h:form>
), or a cancel button which incorrectly submits the form. Such a button would break when you start to actually need the immediate="true"
the right way on one of the inputs. You'd better put such a logout button in its own form, or to change it to process only itself (process="@this"
in PrimeFaces). And you'd better change such a cancel button to just refresh the page synchronously by <h:button value="Cancel" />
. This works fine if the form is tied to a request/view scoped bean and browser caching is disabled on dynamic pages.
See also:
- Should immediate="true" never be used when dealing with an AJAXified JSF 2.0 component?
- Trying to understand immediate="true" skipping inputs when it shouldn't