dojox/mvc/at

Authors:Akira Sudoh, Ed Chatelain
Developers:Akira Sudoh, Ed Chatelain
since:V1.8

dojox/mvc/at API

The module’s value is an at function that can be directly called to create a pointer (called at handle) to a dojo/Stateful property. The at function is in form shown below, which returns an at handle:

at(target, targetProp);

The following parameters should be provided to the at function:

  • target - This is the dojo/Stateful to point to, or a string either in rel:target or in widget:widgetid format. rel:target format looks for a particular property in the parent widget (see Relative data binding for more details). widget:widgetid format looks for a widget with widgetid ID.
  • targetProp - This is the dojo/Stateful property name in target, or *. Using * means “all properties”. (See dojox/mvc/sync:Wildcard syntax for more details)

at function syntax with widgets

at function is typically used as a mixin property of a widget (data-dojo-props or the first parameter of widget’s constructor), in below forms, where in both cases the value property in above TextBox is synchronized with target.targetProp:

<script type="dojo/require">at: "dojox/mvc/at"</script>
<input data-dojo-type="dijit/form/TextBox"
 data-dojo-props="value: at(target, 'targetProp')">
require(["dojo/Stateful", "dijit/form/TextBox", "dojox/mvc/at"], function(Stateful, TextBox, at){
  var target = new Stateful({targetProp: "foo"});
  var textbox = new TextBox({
    value: at(target, targetProp)
  }, srcNodeRef);
  textbox.startup();
});

Basic examples

In the example below, after two seconds, the text box changes from “Foo” to “Bar” as the value property in model changes.

require([
    "dojo/parser", "dojo/when", "dojo/Stateful", "dojo/domReady!"
], function(parser, when, Stateful){
    model = new Stateful({value: "Foo"});
    when(parser.parse(), function(){
        setTimeout(function(){ model.set("value", "Bar"); }, 2000);
    });
});
<script type="dojo/require">at: "dojox/mvc/at"</script>
<input type="text"
 data-dojo-type="dijit/form/TextBox"
 data-dojo-props="value: at(model, 'value')">

In the example below, edit in text box is reflected to the text next to it:

require([
    "dojo/parser", "dojo/domReady!"
], function(parser){
    parser.parse();
});
<script type="dojo/require">at: "dojox/mvc/at"</script>
<span data-dojo-id="model"
 data-dojo-type="dojo/Stateful"
 data-dojo-props="value: 'Foo'"></span>
<input type="text"
 data-dojo-type="dijit/form/TextBox"
 data-dojo-props="value: at(model, 'value')">
<span data-dojo-type="dijit/_WidgetBase"
 data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at(model, 'value')"></span>

Data binding direction

By default, at function used with widget watches for changes both to target.targetProp and the property (attribute) in widget and reflects one change to another. at function allows the direction to be specified via direction function of at handle, which takes one of the following as its first argument:

  • at.from - Only reflect changes in target.targetProp to the property (attribute) in widget
  • at.to - Only reflect changes in the property (attribute) in widget to target.targetProp
  • at.both - Reflect changes in each other (Default)

The basic usage of direction function is shown below, where change in target.targetProp will be reflected to value in TextBox, but not in the opposite direction:

require([
    "dojo/parser", "dojo/when", "dojo/Stateful", "dojo/domReady!"
], function(parser, when, Stateful){
    model = new Stateful({value: "Foo"});
    when(parser.parse(), function(){
        setTimeout(function(){ model.set("value", "Bar"); }, 2000);
    });
});
<script type="dojo/require">at: "dojox/mvc/at"</script>
<span data-dojo-type="dijit/_WidgetBase"
 data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'},
                  value: at(model, 'value')"></span>
<input data-dojo-type="dijit/form/TextBox"
 data-dojo-props="value: at(model, 'value').direction(at.from)">

See dojox/mvc/sync:Data binding direction for more details.

Data converter

at function used with widget allows target.targetProp and property (attribute) in the widget to have a different format as they are synchronized, for example, target.targetProp to have Number 2 and property (attribute) in widget to have String "2". It’s done via transform function of at handle, as shown below:

<script type="dojo/require">at: "dojox/mvc/at"</script>
<input data-dojo-type="dijit/form/TextBox"
 data-dojo-props="value: at(target, 'targetProp').transform({
                    format: function(value){
                      return '' + value;
                    },
                    parse: function(value){
                      return value - 0;
                    }
                  })">

transform function can be used with any objects having format/parse functions, like dojo/number and dojo/date/locale. For example, dojo/date/locale can be used with transform function, as shown below:

require([
    "dojo/parser", "dojo/domReady!"
], function(parser){
    parser.parse();
});
<script type="dojo/require">at: "dojox/mvc/at", dateLocale: "dojo/date/locale"</script>
<span data-dojo-id="model" data-dojo-type="dojo/Stateful" data-dojo-props="value: new Date"></span>
<span data-dojo-type="dijit/_WidgetBase"
 data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'},
                  constraints: {selector: 'date'},
                  value: at(model, 'value').transform(dateLocale)"></span>
<input data-dojo-type="dijit/form/DateTextBox"
 data-dojo-props="value: at(model, 'value')">

The constraints attribute in the non-editable UI showing date is passed as the 2nd parameter to format/parse functions.

See dojox/mvc/sync:Data converter for more details.

Relative data binding

When rel:propInParent format (propInParent can be omitted here) is specified in the first argument of at function, it goes up DOM hierarchy to find a widget meeting the following criteria:

  • The property in widget pointed by widget[widget._relTargetProp] (or widget.target as the default) exists -OR-
  • Such property is defined in the widget class

Then widget[widget._relTargetProp || "target"].propInParent (or simply widget[widget._relTargetProp || "target"] if propInParent is omitted) will be used as data binding target, which the property in widget specified in data binding syntax will be in sync with. When the binding target changes, the data binding will be reestablished with the newer target.

The basic usage of relative data binding is as shown below, where after two seconds, the text box changes from “Foo” to “Bar” as the parent widget for relative data binding (having target property) changes its target property from the one having “Foo” to the one having “Bar”:

require([
    "dojo/parser", "dojo/when", "dojo/Stateful", "dojo/domReady!"
], function(parser, when, Stateful){
    model = new Stateful({child: {value: "Foo"}});
    when(parser.parse(), function(){
        setTimeout(function(){ model.set("child", new Stateful({value: "Bar"})); }, 2000);
    });
});
<script type="dojo/require">at: "dojox/mvc/at"</script>
<div data-dojo-type="dijit/_WidgetBase"
 data-dojo-props="target: at(model, 'child')">
    <input data-dojo-type="dijit/form/TextBox"
     data-dojo-props="value: at('rel:', 'value')">
</div>
Error in the documentation? Can’t find what you are looking for? Let us know!