JSF component binding without bean property
Asked Answered
J

1

13

How does exactly the following code work:

#{aaa.id}
<h:inputText id="txt1" binding="#{aaa}"/>

I mean, usually the component binding works, by specifying a property (of type UIComponent) in a bean. Here, there's no bean nor property but nevertheless the name "aaa" gets bound correctly (displaying the component id - "txt1"). How does it work/where is it specified?

Thanks

UPDATE: The JSF2.0 Spec [pdf] (Chapter 3.1.5) says:

"A component binding is a special value expression that can be used to facilitate “wiring up” a component instance to a corresponding property of a JavaBean... The specified ValueExpression must point to a read-write JavaBeans property of type UIComponent (or appropriate subclass)."

Jessalyn answered 17/11, 2011 at 13:58 Comment(0)
S
19

It's been put in the default EL scope during building of the view tree (that's when all binding attributes -- and attributes of tag handlers like JSTL <c:xxx> and JSF <f:xxx> -- are being evaluated). It's being shown by normal EL means during rendering of the view tree. Rendering of the view tree happens after building of the view tree, so it works that way. It's not that this code runs "line by line" as you seemed to expect from the source.

I can't point you out a single reference where it's been specified as there is none. You'd have to read both the EL spec and JSF spec separately and do a 1+1=2.

By the way, to avoid confusion among new developers and to avoid clashes with existing variables in the EL scopes, you can use a java.util.HashMap in the request scope which is been declared as follows in faces-config.xml:

<managed-bean>
    <description>Holder of all component bindings.</description>
    <managed-bean-name>components</managed-bean-name>
    <managed-bean-class>java.util.HashMap</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

and is been used as follows

#{components.aaa.id}
<h:inputText id="txt1" binding="#{components.aaa}"/>

which is more self-documenting.

See also:

Sevier answered 17/11, 2011 at 14:7 Comment(7)
Thanks BalusC for reply. I have indeed seen it many times in your code. The rendering is naturally clear, I meant rather the point how is the name bounded. I have updated the post with an excerpt from JSF Spec which explicitly says the given ValueExpression must be a Bean property.Jessalyn
You can also interpret EL as "one big virtual javabean". On binding, JSF will examine if the property already exists and if so, then get the component from it (which MUST indeed be an instance of the proper subclass) and if not, then just autocreate the component and put in there. Note that the property type can be Object or any other superclass of the component instance.Sevier
OK, I like this interpretation. So the conclusion is, that the "binding" attribute serves as a way, to save sth (in this case - the component) in the scope of EL. Interesting.Jessalyn
just mentioning it because I had to (partly) realize it myself: e.g. #{components.aaa} is a bad example. Better would be #{components[myAbsolutelyUniqueId]} - unique because if you have, say 2 panelGrids or datatables, the same Id will be valid in both since jsf prefixes it. It will be valid in different forms as well.Georgiannageorgianne
h:inputText with binding="#{var}" is throwing an exception when entering a numerical value. Are there any erstrictions for numbers? Which type of objects can be used?Araucaria
@Wecherowski: that's a different problem. The binding represents the UIComponent itself, not its value property.Sevier
I see the difference now. ThanksAraucaria

© 2022 - 2024 — McMap. All rights reserved.