To define a binding in a template, wrap the binding source
property name between doubled curly brackets {{ }}. Set it in quotation
marks for string values of the binding destination property.
For example, to bind the
text
property
of the text shape to the label
property
of the node:shape:{type:'text', text:'{{label}}' }
To bind a source property with a number data type that
you want to express as a number value for the destination property,
you must apply the template parameter as a JavaScript object property.
See Defining parameters as JavaScript object properties.
Binding source
The source of a binding can be:
- A property of the target object that follows the Java property naming conventions: for a 'foo' property, there must be a getFoo() method.This property is called a bindable property.
- A public property of the target object.
- A method of the target object. For example, text:'node {{getId}}'.
- An attribute of a data store item. See the section Binding to data store items.
The binding engine supports chained properties in the
form
a.b.c.
where a, b, and c corresponds
to one of the supported binding sources. For example, the following
property displays the width of the node bounds:text:'{{getBounds.width}}'
Binding to data store items
If you use the Diagram widget and connect to a data store
to populate a graph, you can define bindings to properties of the
data store items through the
data
property
of the node. This property defines the data context associated with
a node been created from a data store item. When you use the data
property
in a binding, it is a shortcut to the underlying data store API, and
allows direct references to data item attributes. For example, a library data store might be populated
with the following items:
{ author: ..., title: ..., ISBN:... }
The following template displays the title and author
in two text shapes:
ibm_ilog.diagram.declareTemplate("[ { shape: { type:'text', text:'{{data.title}}' } }, { shape: { type:'text', text:'{{data.author}}' } } ]");
In addition to data item attributes, a data store binding
can also reference methods of the dojo.data.api.
The supported methods are:
- getIdentity
- getLabel
- getAttributes
For example, you could change the template to display
the identity of the data item instead of its title:
ibm_ilog.diagram.declareTemplate("[ { shape: { type:'text', text:'{{data.getIdentity}}' } }, { shape: { type:'text', text:'{{data.author}}' } } ]");
Because the binding engine is based on the Django Template
Language (DTL), you can use all the advanced features that the Dojo
implementation of DTL supports. For example, the following template
uses DTL for a loop script. It iterates over a user-defined members property
(defined as an array) to create a Text shape for each item in the
array. The shapes are automatically arranged in a vertical stack by
the StackLayout layout.
ibm_ilog.diagram.declareTemplate("{ layout:{type:'ibm_ilog.diagram.gfxlayout.GridLayout'}, children:[{ shape:{ type:'rect', width:1, height:1 }, fill: '{{backgroundColor}}', stroke: {'color': 'black', 'width': 2 } }, { layout:{ type:'ibm_ilog.diagram.gfxlayout.StackLayout', horizontal:false, gap:3, padding:[5,5,5,5]}, children:[ {% for m in members %} { shape:{ type:'text', text:'{{m}}', align:'middle' }, fill:'{{textColor}}', font:{type:'font', size:'10pt', family:'sans-serif'} } {% if not forloop.last %},{% endif %} {% endfor %} ] } ] }");
Defining parameters as JavaScript object properties
In the examples given in the previous section, all the
binding parameters are expressed as strings. The syntax used to define
the binding,
{{ ... }}
, is not compliant
with JavaScript, and therefore can prevent the template from being
written as a plain JavaScript object. It is not an issue when the binding expression is quoted,
that is, when the variable that receives the binding expects a string,
for example,
text: '{{label}}'
. It becomes
a blocking issue when you want a bound parameter to be something other
than a string, for example, x: {{elemWidth}} + 10
.
Here, you typically want to pass the elemWidth
parameter
as a number data type to the target object. Even when you can express
all the template parameters as strings, it can make writing complex
templates cumbersome (for example, templates with multiline strings).
It is also error-prone because a syntax error in the template itself
might be hard to detect. To avoid these problems, express the template parameters
as JavaScript objects and use the $bind() global
function of the templating engine to define the bindings that cannot
be quoted. For example, if
abscissa
and ordinate
properties
are defined on the object to which the template is applied and these
properties return a number that you want to use to place the shape
in the graph, the template declaration might look like the following
example:var t = ibm_ilog.diagram.declareTemplate({ shape:{ type:'rect', x: $bind("{{abscissa}}"), y: $bind("{{ordinate}}") } }); var node = graph.createNode(t);
Using the declareTemplate function
All templates can be declared using the ibm_ilog.diagram.declareTemplate() function.
This optional function processes the template so that it is ready
to be used by the templating engine when it is applied on a shape.
If you do not declare your template through the declareTemplate() function,
the template is processed by the templating engine each time it is
applied. It can have a significant performance cost when your graph
contains many nodes. While this function can be used for every template,
it must be used particularly for templates that define bindings.
When a template has been declared through this function, it must not
be modified.