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)."

YoYo
  • 9,157
  • 8
  • 57
  • 74
jarek.jpa
  • 565
  • 1
  • 5
  • 18

1 Answers1

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:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 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. – jarek.jpa Nov 17 '11 at 14:16
  • 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. – BalusC Nov 17 '11 at 14:23
  • 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. – jarek.jpa Nov 17 '11 at 14:49
  • 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. – Toskan Aug 30 '12 at 17:16
  • 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? – Wecherowski Sep 15 '16 at 22:55
  • @Wecherowski: that's a different problem. The binding represents the `UIComponent` itself, not its `value` property. – BalusC Sep 16 '16 at 07:27
  • I see the difference now. Thanks – Wecherowski Sep 16 '16 at 07:55