In this example, we use a Details control to illustrate the use of binding containers .
Binding containers are controls that provide scoping for bindings. In other words, any controls within a binding container look to that binding container for values for bindings.
To illustrate this, we're showing the Details controls, one of Jitsu's built-in binding containers.
The markup:
<j:Details item="#bind(data.lifeforms.elephant)">
creates a Details control. Here we are binding the "item" property of the details control to "data.lifeforms.elephant" - we're creating a binding between the "item" property on Details and the lifeform whose id is "elephant" in the "lifeforms" dataset we loaded into this page.
Next, inside the Details control, we have some controls e.g.
<j:Label text="#bind(item.name)"/> <img src="#bind(item.imageUrl)"/>
This is binging against the Details control's "item" property, and using that property to show details of the object - here we are showing the images name and image.
This illustrates another important point about binding: You can have chained bindings. The Label binds to the Details control, which in turn binds to the Person in the "people" dataset. When changes occur, they propagate all the way up the binding chains.
Here's how it works: To resolve a path on a control or element, the binding engine skips up the control hierarchy until it hits a control whose "isBindingContainer" property is set to true. Then it examines that control for a property whose name matches the first element in the binding path. If the property exists, it then follows down the path until it hits the destination of the binding.
BindingContainers therefore establish a "namespace" - they let you introduce new names, scoped to the binding continer, which child elements can resolve against.
The root of the control hierarchy (the "AppControl") is always a binding container. That's where the application's datasets live (on the "data" property of the AppControl). But you can also introduce new binding containers within the control hierarchy.
Sometimes when you are inside a binding container, you need to bind to something that is in its parent container, or possibly in the root AppControl.
To do that, you use a ../
or //
prefix on the binding path, e.g.
#bind(../item.firstName) #bind(//data.people.fred.firstName)
The "../" prefix tells the binding engine to go up two levels of binding containers instead of one.
The "//" prefix tells the binding engine to look at the root binding container (the body control).
We'll come back to Details in the Master/Detail example. Next, lets look at List controls.