Defining a binding

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.