Tapestry components are designed to work with each other, within the context of a page and application. The process of rendering a page is largely about pulling information from a source into a component and doing something with it.
For example, on a welcome page, a component might get the userName
property from
the visit
object and insert it into the HTML response.
Each component has a specific set of parameters. Parameters have a name, a type and may be required or optional.
To developers experienced with Java GUIs, it may appear that Tapestry component parameters are the same as JavaBeans properties. This is not completely true. JavaBeans properties are set-and-forget; the designer sets a value for the property using a visual editor and the value is saved with the bean until it is used at runtime.
Parameters define the type of value needed, but not the actual value. This value is provided by a special object called a binding. The binding is a bridge between the component and the parameter value, exposing that value to the component as it is needed. The reason for all this is to allow pages, and the components within them, to be shared by many concurrent sessions ... a major facet in Tapestry's strategy for maintaining application scalability.
When a component needs the value of one of its parameters, it must
obtain the correct binding, an instance of interface IBinding
,
and invoke methods on the binding to get the value from the binding.
Additional methods are used with output parameters to update the binding property.
In most cases, discussed in the next section, Tapestry can hide the bindings from the developer. In effect, it automates the process of obtaining the binding, obtaining the value from it, and assigning it to a JavaBean property of the component.
There are two types of bindings: static and dynamic. Static bindings are read-only; the value for the binding is specified in the component specification.
Dynamic bindings are more prevalent and useful. A dynamic binding uses a JavaBeans property name to retrieve the value when needed by the component. The source of this data is a property of some component.
In fact, dynamic bindings use property paths, allowing a binding to 'crawl' deeply through an object graph to access the value it needs. This frees the components from relying totally on the properties of their container, instead they are free to access properties of more distant objects.