Binding data and configuration options
A coach view may be associated with a data binding and configuration options. The view context provides access to this data. To access binding data and configuration options you must use the JavaScript get and set functions. You cannot use JavaScript dot notation.
context.binding
The binding object, if defined, provides access to data that is bound to a view. There is at most one data binding declared for each view.
You can access data that is bound to a view by using the construct: this.context.binding.get("value"), where value is a special property name that returns the data binding. For example, if a view is bound to local.phoneBook.title, then the view can get the phone book's title as follows:
if (!! this.context.binding){
var title = this.context.binding.get("value")
}
The main reason for views to bind to data is so that
the view can be notified if the bound data has been modified. The
view framework detects data changes in the bound object, and automatically
notifies the view by calling its change event handler
function. It is important to note that these notifications will be
sent to the view only if the binding object itself changes, but not
if any of its properties or sub-properties change. The following sections
discuss the different data types and outline the cases where additional
code is required for the view to receive notification of a data change.Binding to simple and complex data types
For simple data types such as strings and numbers, the view framework detects data changes and automatically notifies the view of the change. For example, when a view is bound to the simple string type local.phoneBook.title, the view's change() function is called with a change event that specifies that the title changed and its new value. All the views that are bound to local.phoneBook.title are notified.
- bind(path, callback, [scope])
- Notifies the view via callback if a specified property has changed. Scope is an optional parameter that specifies the context scope of the callback. Returns a handle to the callback.
- bindAll(callback, [scope])
- Notifies the view via callback if any property on the object has changed. Scope is an optional parameter that specifies the context scope of the callback. Returns a handle to the callback.
For the callback signature, see the function(event) topic.
var binding = this.context.binding.get("value"); //this is a complex object
this.property2Handle = binding.bind("property1.property2", function(e) {some code}, this);
this.property3Handle = binding.get("property3").bindAll(this.myBindAllChangeHandler, this);
......
this.mybindAllChangeHandler(event) { .....};
In the
example, the view is bound to a complex object and sets a change handler
to be notified if binding.property1.property2 (which
is a string) changes. It also sets another change handler to be notified
if any sub-property of property3 changes. In both
cases the scope in which the change handler is called is the view's this scope. Binding to a list type
When you bind to a list, the view is automatically notified when the entire List object changes. For example, consider that the view is bound to the list local.phoneBook.person[]. If a new person list is created and set to the view's binding, for example using the server script syntax tw.local.phoneBook.person = new tw.object.listOf.person(); the framework automatically notifies the view of the change.
Binding to list updates
var binding = this.context.binding.get("value"); //this is a List object
this.bindAllHandle = binding.bindAll(this.listUpdated, this);
Binding to list properties
In addition to the elements of a list, a list also has special properties, such as a property that defines the list elements that are selected by a user. The special properties are described in the following table.Property | Type | Description |
---|---|---|
listAllSelectedIndices | Array | The indexes of the list elements that are selected by a user. There can be more than one selected index. When you set listAllSelectedIndices, you pass in the indexes in an array. Use listAllSelectedIndices when updating the list selection. |
listAllSelected | Array | An array of all the elements that a user has selected. Use listAllSelected to subscribe to a change to this property. This property is read-only. |
listSelectedIndex | Integer | The index of the selected element. This value corresponds to the value of the index 0 element of the listAllSelectedIndices array. Use listSelectedIndex to subscribe to a change to this property. This property is read-only. |
listSelected | Object | The selected element. This value corresponds to the value of the index 0 element of the listAllSelected array. Use listSelected to subscribe to a change to this property. This property is read-only. |
var binding = this.context.binding.get("value"); //this is a list
this.selectedIndicesHandle = binding.bind("listAllSelectedIndices", this.indicesChanged, this);
Accessing list elements
- Use get("value") to get the list object. For example: list = this.context.binding.get("value")
- Use get(index) to obtain the indexed element. For example: list.get(0) to obtain the first element.
- Use get(property) to obtain the value of the property. For example: list.get("listSelected") to obtain the value of the listSelected property. Use similar syntax to obtain the values of all other properties.
- Use items to get an array that represents the underlying elements of the list. For example, list.items. The data returned by items should not be modified.
List operations
The following APIs are used to modify a list and to get information about a list.- To add an object, use list.add(item). For example, this.context.binding.get("value").add(item)
- To remove an object, use list.remove(index), For example, this.context.binding.get("value").remove(0)
- To replace an object, use list.put(index, item). For example, this.context.binding.get("value").put(0, item)
- To get the length of a list, use list.length().
- To get an indexed element or property of the list, use list.get(index | property). For more information, see Accessing list elements.
- To programmatically update the selected property in the list, use list.set(property). For example, this.context.binding.set("listAllSelectedIndices , [1, 2, 3]);
Cleaning up bound resources
if (event.type != "config"){
var binding = this.context.binding.get("value"); //this is a list
// assumes that this.selectedIndicesHandle was initialized in the load function
this.selectedIndicesHandle.unbind();
this.selectedIndicesHandle = binding.bind("listAllSelectedIndices", this.indicesChanged, this);
// assumes that this.selectedIndicesHandle was initialized in the load function
this.bindAllHandle.unbind();
this.bindAllHandle = binding.bindAll(this.listUpdated, this);
}
Configuration options
In addition to data, views also can be bound to configuration options. A view can have multiple configuration options. For example, the label of a button control is a configuration property. The values for the configuration can be retrieved using the view's this.context.options object. The object context.options contains a predefined metadata property in addition to user-defined properties that are configurable for a view.Option | Type | Description |
---|---|---|
label | String | The label value of the view, if one exists |
visibility | String | The visibility settings for the view. Valid values are:
"DEFAULT" | "EDITABLE" | "REQUIRED" |
"READONLY" | "NONE" | "HIDDEN". See The coach view context object. DEFAULT is the code equivalent to Same as
parent that users see on screen in a Visibility list. Important: Tables have
a Disable click-to-edit configuration property. The default value is false,
which means that Coach Views contained within that table use the visibility settings of the table.
That is, the Coach Views in a given cell are READONLY until the user clicks in the
cell. The Coach Views are then EDITABLE until the user clicks anywhere outside of
the cell. The Coach Views revert to being READONLY. When Disable
click-to-edit is true, these Coach Views use their own visibility settings.
Important: Setting the visibility to REQUIRED does not
validate whether a user has entered or set a value. You must provide code that does this checking
by, for example, implementing a validation service for the Coach that contains the Coach
View.
|
labelVisibility | String | The visibility settings for the label. Valid values are "SHOW" | "HIDE" |
helpText | String | The view can use this property as hover text |
className | String | The CSS class name(s) specified. Normally a view does not need to use this as the CSS class names are inserted into the view's DOM attribute |
htmlOverrides | Map | A name-value pair map that represents the HTML attribute specified. These name-value pairs are inserted into the view's DOM attribute |
- To get a view's predefined options, use this.context.options._metadata.*. For example, to get a view's visibility option, use this.context.options._metadata.visibility.get("value");
- To set a view's predefined options, use this.context.options._metadata.*. For example, to set a view's visibility option, use this.context.options._metadata.visibility.set("value", newValue);
- To get a user defined configuration option, use this.context.options.myOption.get("value");, where myOption is the option name.
- To set a user defined configuration option, use this.context.options.myOption.set("value", newValue);, where myOption is the option name.
To serialize the data binding object to a JSON string, you can call the toJson() function on the data binding object. To get a basic JavaScript object that represents the data binding, you can call toJSObject().