-
Notifications
You must be signed in to change notification settings - Fork 1
Data Binding
Data binding is the mechanism that allows user interface elements in a "View" to be linked directly to data and/or commands in a "View Model".
Consider the following View and View Model:
View:
{ control: "stackpanel", orientation: "Horizontal", contents: [
{ control: "text", value: "First name:" },
{ control: "edit", binding: "firstName" }, // << Edit control bound to firstName
] },
{ control: "stackpanel", orientation: "Horizontal", contents: [
{ control: "text", value: "Last name:" },
{ control: "edit", binding: "lastName" }, // << Edit control bound to lastName
] },
{ control: "text", value: "Welcome {firstName} {lastName}" }, // << Text composed from bound values
View Model:
viewModel =
{
firstName: "John",
lastName: "Smith",
}
In this example, edit controls for first and last name will be pre-populated with the values "John" and "Smith" respectively, and the welcome string will be set to "Welcome John Smith". As the end user changes the value in either edit control, the associated value in the view model will be updated in real time, and that will trigger the simultaneous update of the welcome string.
In Synchro, data binding is the only method that applications have to populate and interact with user interface elements, and for that reason the Synchro data binding system is necessarily comprehensive (supporting literally every possible interaction).
###Property Binding
- Can be used in any attribute of any element
- Multiple bindings can be aggregated in an attribute
- One way (or one time using
^
notation) - Can use format specifiers, for example
{screenSizeInches:F2}
(formats as a fixed point number with two decimal places).
For supported format specifiers, see: http://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx
###Value Binding
- Can be used on certain elements
- Specified in the "binding" attribute
- Value binding (if any) is two-way, linked to a single data item in the view model
- Zero or more bound commands
Accessing view model data in a binding specification uses a path syntax. Consider the view model below:
viewModel =
{
person:
{
firstName: "John",
lastName: "Smith"
},
colors:
[
{ name: "Red", value: "FF0000" },
{ name: "Green", value: "00FF00" },
{ name: "Blue", value: "0000FF" }
],
answer: 42
}
- To access a simple value, use the property name, for example:
answer
- To access an object property, use dot notation, for example:
person.firstName
- To access an array element, use square bracket notation with a numeric (0-based) index, for example:
colors[1]
- These notations can be combined as required, for example:
colors[1].name
Each user interface element has a "binding context", provided by its container or parent element, which specifies the item in the view model on which its bindings will be based. At the top level, the binding context is the view model itself (as in the binding paths examples above).
Generally, the binding context for a given element is passed on to any child or contained element. However, some container elements modify the binding context passed their child or contained elements. For example, a list view element might create a binding context for each item in the underlying bound array, and pass those binding contexts to each child element (so each list item element is bound to a corresponding item in the array).
Elements can also alter their own binding context by using the foreach
and/or with
attribute in their binding specification. These binding context operations are applied before any property or value binding is processed for the element.
The foreach
binding attribute creates an instance of the element for each instance of the array referenced by foreach
. For example, using the View Model above:
{ control: "text", value: "Color: {name}", binding: { foreach: 'colors' } }
will yield three text controls, one for each color, each displaying the name of the color.
The with
binding attribute selects a new context by applying the provided path to the current binding context. For example, using the view model above:
{ control: "text", value: "Hello {firstName} {lastName}", binding: { with: 'person' } }
will yield a text control with a welcome value using the first and last name from the 'person' property of the view model. Since with
specified 'person', the binding context for the element was the person property, and the name values referenced are relative to that binding context.
It is possible to used both foreach
and with
in a single binding specification, using the foreach
to select the context to be iterated, and then using with
to further select properties of each iterated item to become the binding context.
It should be clear that each element has a binding context, and that that binding context can refer to any item anywhere in the view model. It is sometimes necessary to refer to values relative to either the root binding context (the view model itself) or the current binding context. The following binding path tokens allow for this:
-
$root
- Selects the root of the view model. -
$parent
- Selects the parent of the current binding context. -
$data
- Selects the value of the current binding context. -
$index
- Produces a numeric value representing the position (zero-based index) of an iterated binding context
- Simple negation using
!
, for example:visibility="{!isVisible}"
- Mathematical, for example
value="{(240 - charCount)}
- Logical, for example:
enabled="{(charCount >= 240)}"
- Type conversion, for example:
value="{str(240 - charCount)}"
Questions or comments? contact Synchro directly
- Getting Started:
- Synchro Server:
- Synchro Modules: