Data binding
last updated on: 03/23/17
| tags: bindings, data, service, readdata, writedata, source
### Binding Syntax
#### Binding specifications
Bindings appear templates that are contained in the view and which declare with an attribute a `data-class`. Once a `data-class` has been attributed to an element, a variety of bindings can be specified within that template. These bindings follow the same syntax rules but their details will vary according their specifi purposes. Thus the specification of the databinding will depend on the target of the binding - the element or object that needs to be bound to some data. Depending on the type of the target some binding features may or may not be available.
* `data-bind-<action>` or `data-bind-<indexedaction>[<key>]` - binding of DOM element properties/features or properties of the active object attached to it. All binding features are available in this case.
* Binding in object parameters will depend on the parameter options and the object being parameterized.
* Binding to active objects: bindings passed as parameters for active objects attached to DOM elements have the potential to support all the framework features unless they are explicitly disabled.
* Binding to passive objects: Bindings passed to indirectly created objects are usually unable to participate in the updateTargets/updateSources operations and can be used only programmatically or from another binding. This is not a limitation, because the very purpose of bindings passed as parameters is to enable the object to fetch data through them when it needs to use the parameter.
The declarative binding specification is as an attribute named after the following pattern: `data-bind-<action>="{ <binding expression> }"`. The element on which the attribute is specified is called target of the binding expression. Extended form of this syntax allows for keyed binding to the same property (action): `data-bind-<action>[key]="{ <binding expression> }"`, which enables the target to work with variable number of data items.
Stating an `<action>` - this part of the attribute name specifies the action that must be performed on the target element on which the attribute is specified. This can be a jQuery-like function name or a method of the bound active class (if such exists). The function must set whatever you want to be set when a single parameter is passed to it and return that value if called without parameters (only if two-way binding is required). This is natural pattern that is based on jQuery. If you want to pass more than one parameter, then you may need toimplement a method in a data-class class that performs the task over the element.
#### Examples
* `data-bind-val={…expression…}` – binds the value of an input element
* `data-bind-html={…expression…}` – binds the inner HTML
* `data-bind-text={…expression…}` – binds the text content in the element.
* `data-bind-checked={…expression…}` – bind to checked property of a checkbox with Boolean data.
* `data-bind-elementdisabled={…expression…}` – disable/enable the element (Boolean).
* `data-bind-checkedn={…expression…}` – bind to checked property of a checkbox but with better support for non-boolean data.
* `data-bind-elementtitle={…expression…}` – bind to the title attribute (String).
* `data-bind-ellipsis={…expression…}` – bind to the inner HTML (String) but honours the binding parameter which can specify a limit to which the text is truncated.
* `data-bind-elementvisible={…expression…}` – hide/show the element (Boolean) using the display CSS style.
* `data-bind-elementvisibility={…expression…}` – hide/show the element (Boolean) using the visibility CSS style.
* `data-bind-indentination={…expression…}` – Specify margin-left in pixels.
*It is recommended to avoid creating jQuery extensions for everything. A better approach would be to create classes and attach them to the elements that need special behaviour. The classes are easier to manage and fit better in the life cycles maintained by the framework. Creating a jQuery extension function intended for usage in bindings is justified only if it will be used extensively in many templates.*
#### Method/pseudo property of a bound object
In order to access a method or a pseudo property of a bound object, it will be needed to have a class that inherits `Base` or `ViewBase` and is bound to this element. This may be done programmatically though in a template it is usually done declaratively by using the `data-class` attribute. In this example, we will assume to have a class `MyClass`, which is declared for the target element:
```html
<sometag data-class=”MyClass” …/>
```
When the template is instantiated an instance of this class will be created and attached to the target DOM element. In the binding we can now specify `data-bind-$aprop={…}`. The `$aprop` part specifies that the binding will use a pseudo property of `MyClass` to get or set the bound data. Thus, `MyClass` will need to implement the methods: `get_aprop()` and `set_aprop(newvalue)`. In situations when the binding is one-way (read-only) we can have only a getter and can omit `set_aprop(newvalue)`.
We can see an example of such binding by looking at the `ImageX` class from the BindKraft framework. It supports `get_src` and `set_src` pseudo properties which set the source of an `image` element. We can specify binding like this:
```html
<div data-class="ImageX" data-bind-$src=”{read path=someprop}” …></div>
```
This binding method allows for greater flexibility than using jQuery-like functions, because it enables us to implement any custom logic that we may need.
***Important!** A limitation for the <action> part of the binding is the requirement for the pseudo property name of for the jQuery-like function name to be lower case only! This is because of the HTML specification for attribute names. Be aware that some browsers (IE for instance) will preserve the casing, but others (Chrome for example) will forcibly convert to all lowercase the attribute names when accessed programmatically and you will lose any upper case letters - this may become a source of mysterious errors occurring only on some browsers!*
#### Binding expressions
The *<binding expression>* deals with the source of the data, which is used in the binding. The object from where the data is obtained is known as the **source** of the binding. It describes where to get the data from and the means to obtain it (i.e . how). This is a list that shows the general syntax currently supported for binding expressions. Note that all the settings are typically written on single line, thpouogh they can be listed on separate lines for human readability. The pipeline character (`|`) signifies the logical *or* and the questions mark (`?`) indicates that the setting is optional.
```javascript
{
bind|read|
[source=<element>|self|static|globalresource]?
[path=<proppath>]?
[format|customformat=<formatter>]?
[flags=<flag1[,flag2[,…]]>]?
[create=object|array]?
[debug=<element>:<method>]?
[text|number='value']?
[object=classname]?
[validator=’<element>’]?
[name=<identifier>]?
[trace=<tracetokens>]?
[onload|onenter|onleave|onclose=<rulename>]*
[parameter|argument=’value’]?
}
```
#### The most common settings: `bind`, `read`, `source` and `path`
##### `bind` and `read`
These specify the kind of binding: `bind` is used for bidirectional and `read` for read-only (only from the source to the target).
##### `source`
The `source` is an optional element, which is needed if the source of the data is not the current data-context. When we access data elements in the current data-context we should omit this part. When we need to read the data from another element from the template or most likely the object bound to it we need to specify the element. This is most often done by using the **key** for the element which is specified using the `data-key` attribute. For example:
```html
<div data-class=”SomeClass” data-key=”somekey” …>
… other elements …
<span data-bind-val=”{read source=somekey path=labels.myLabel}”></span>
… other elements …
</div>
```
The `source` is the parent element with the `data-key` specified by the source binding parameter. The search for the key is only over the parents and **will not stop at the template border – it will continue to the root of the HTML document**. One should ensure that the `data-key` specified exists in the template unless he/she intentionally wants to bind to an element in a parent template.
As a special case the key `self` is processed in special manner (it is a reserved `data-key` and should not be used) and refers to the current element.
The source is either the DOM element or the object attached to it using data-class attribute (this attachment can be performed also programmatically, of course). If the referred source element (including `self`) has an object attached to it, then this object is the source, if not the DOM element itself is the source. **It is recommended to avoid binding to DOM element sources, because they may change or otherwise complicate the template functionality.** Using a class ensures that you can implement custom logic or provide access to a specific data not included in the data-context or the DOM. When using source parameter pseudo properties are a logical choice.
##### `path`
The `path` specifies the path to the data value to be bound. The `path` may consist of any number of elements separated with the period character (`.`). Pseudo properties are supported by specifying a link in the path chain with the dollar (`$`) prefix. The `path` specifies the properties to be traversed over the specified source or the data-context in order to reach the desired value. Therefore `path=a.b.c` means that the value will be obtained from the `a` property of the source object, then the `b` property of the returned by the `a` property object then the `c` property of the last one. If one of these properties is a pseudo property, then we can specify it like this: `path=a.$b.c`, which means that the property `b` will be in fact a combination of `get_b()` and `set_b(newval)` methods available on the object `a`. This pseudo property syntax works for both data-context source and a source specified by using the `source` parameter. However pseudo properties are typically implemented only by objects attached to elements (using data-class attribute) and very rarely in data-contexts or over raw DOM elements. This means that in most cases usage of pseudo properties without source parameter is an indication for a mistake.
For example, we can have a data-context that contains the following object:
```javascript
{
name: “John”,
age: 35,
spouse: { name: “Georgina”, Age: 105}
}
```
We can display the age of the spouse in a text box like this:
```html
<input type=”text” data-bind-val=”{bind path=spouse.Age}” />
```