backbone-epoxy-docs

View Binding Handlers

Overview

Binding handlers are used to interchange model data with elements in the view. The Epoxy View includes default binding handlers for common tasks such as managing a bound element’s content, class, and style. However, don’t feel limited to just Epoxy’s out-of-the-box binding handlers. You may easily define your own binding handlers within a view.

One or more binding handlers may be applied to an element as a comma-separated properties list (here shown using DOM attribute bindings):

<a data-bind="text:linkText,attr:{href:linkUrl,title:linkText}"></a>

In the above example, “text:” and “attr:” are binding handlers, while “linkText” and “linkUrl” are the bound model attributes assigned to them. In the case of the “attr” handler, its value is a hash of attribute names, each with an associated model value.

Be aware that binding declarations are parsed as JavaScript Object bodies, therefore a binding declaration must conform to proper JavaScript syntax. To give due credit, Epoxy’s binding system is modeled after the clever technique used in Knockout.js. However, Epoxy deliberately limits some of Knockout’s free-form binding allowances, such as inline concatenation (which becomes overly technical within the presentation layer, IMHO). If you’re coming from Knockout, don’t expect to write as much inline binding JavaScript.

attr

read-only data-bind="attr:{name:modelAttribute,'data-name':modelAttribute}"

Binds model attribute values to a list of element attributes. Attribute bindings are defined as a hash of key/value pairs, where each key defines an element attribute and the model reference defines the attribute value. Attribute keys may be defined as strings.

checked

read-write data-bind="checked:modelAttribute"

Binds checkbox and radio elements to the model. The binding behavior differs slightly for various element/value combinations:

classes

read-only data-bind="classes:{active:modelAttr,'is-active':modelAttr}"

Toggles a list of element class names based on the truthiness of their bound model attributes. Class bindings are defined as a hash of key/value pairs, where each key defines a class name and is value references a model attribute that will be loosely-type checked for truthiness; truthy attributes will enable their class, while falsey attributes will disable their class. Class name keys may be defined as strings.

collection

read-only data-bind="collection:$collectionSource"

Manages the display of a Backbone.Collection. The bound collection must specify a Backbone.View constructor for displaying its models, at which time the collection handler will manage adding, removing, resorting, and resetting a list of those views to synchronize the display of the collection’s contents. The collection binding performs discrete view management, where collection models will be assigned a single view instance for their lifespans, rather than re-rendering all collection views in response to changes. You may choose to use an Epoxy.View constructor for the display of individual collection items, allowing each collection view item to bind to its respective model.

The collection binding requires the following setup:

// View for individual collection items:
var ListItemView = Backbone.View.extend({
    tagName: "li",
    initialize: function() {
        this.$el.text( this.model.get("label") );
    }
});

// Collection defining a Model and View:
var ListCollection = Backbone.Collection.extend({
    model: Backbone.Model
});

// Binding view for list of collection items:
var ListView = Backbone.Epoxy.View.extend({
    el: "<ul data-bind='collection:$collection'></ul>",
    itemView: ListItemView,
    initialize: function() {
        this.collection = new ListCollection();
        this.collection.reset([{label: "Luke Skywalker"}, {label: "Han Solo"}]);
    }
});

var view = new ListView();

Note that the collection binding does not register a “change” event on its collection to avoid generally superfluous updates. Instead, you may manually trigger an “update” event on the collection to refresh its bindings. For a working demonstration of the collection binding, see the Epoxy ToDos demo.

css

read-only data-bind="css:{color:modelAttribute,'font-size':modelAttribute}"

Binds a list of CSS styles to model attributes. CSS style bindings are defined as a hash of key/value pairs, where each key defines a CSS style name and the model attribute defines the style’s literal value. CSS keys may be defined as strings.

disabled

read-only data-bind="disabled:modelAttribute"

Toggles a form element’s “disabled” property based on a loosely-typed assessment of the bound model attribute’s truthiness. A truthy value disables the element (inversion of the enabled handler).

enabled

read-only data-bind="enabled:modelAttribute"

Toggles a form element’s “disabled” status based on a loosely-typed assessment of the bound model attribute’s truthiness. A truthy value enables the element (inversion of the disabled handler).

events

read-only data-bind="events:['keydown','focus']"

The events handler is a special binding used to parameterize what DOM events will trigger changes for read-write element bindings. By default, all read-write bindings will subscribe to their bound element’s “change” event to trigger model updates. You may bind additional DOM event triggers for the element by listing them in the events array.

html

read-only data-bind="html:modelAttribute"

Sets the element’s HTML content to the bound model attribute value. Uses the jQuery html method.

itemView

read-only data-bind="collection:$collection,itemView:'myView'"

The itemView handler is a special binding used to parameterize what view is used to render collection binding items. By default, a collection binding will access its parent view for a property called “itemView”. Use the itemView binding to specify a different attribute of the parent view. This may be useful when binding multiple data sources.

options

read-only data-bind="options:arraySource"

Binds a

defaults: {
    list1: ["Luke"],
    list2: [{label:"Luke", value:"0"}],
    list3: new Backbone.Collection( {models:[{label:"Luke", value:"0"}]} )
}

// list1: <option value='Luke'>Luke</option>
// list2: <option value='0'>Luke</option>
// list3: <option value='0'>Luke</option>

To manage a

optionsDefault

read-only data-bind="options:opts,optionsDefault:modelAttribute"

Defines a default option made available at the top of a

defaults: {
    default1: "Choose...",
    default2: {label:"Choose...", value:""},
    default3: new Backbone.Model({label:"Choose...", value:""})
}

// default1: <option value='Choose...'>Choose...</option>
// default2: <option value=''>Choose...</option>
// default3: <option value=''>Choose...</option>

You may also choose to declare optionsDefault as a static object within a binding declaration, as in:
data-bind=”value:val,options:opts,optionsDefault:{label:’Choose…’, value:’’}”

optionsEmpty

read-only data-bind="options:opts,optionsEmpty:modelAttribute"

Defines a placeholder option to apply to an empty

defaults: {
    empty1: "None",
    empty2: {label:"None", value:""},
    empty3: new Backbone.Model({label:"None", value:""})
}

// empty1: <option value='None'>None</option>
// empty2: <option value=''>None</option>
// empty3: <option value=''>None</option>

You may also choose to declare optionsEmpty as a static object within a binding declaration, as in:
data-bind=”value:val,options:opts,optionsEmpty:{label:’none’, value:’’}”

template

read-only data-bind="template:$source"

The template binding extracts its element’s HTML content while initializing, and then parses that content into an Underscore template using the bound data. You have some options on how both the template string and the bound data sources are defined.

Defining the template string

When the template binding initializes, it will extract content from its element to use as the template string. However, to safeguard against malformed HTML within the DOM, the template binding will first search its element for a

<div data-bind="template:$model">
    <script type="text/tmpl"><%= firstName %> <%= lastName %></script>
</div>

<div data-bind="template:$model">
    <template><%= firstName %> <%= lastName %></template>
</div>

If a

<div style="display:none;" data-bind="template:$model,toggle:true">
     
</div>

Defining data sources

The template binding may specify data sources in a few different ways. First, let’s assume the following example view configuration:

var MyView = Backbone.Epoxy.View.extend({
    el: "#my-view",
    model: new Backbone.Model({
        firstName: "Luke",
        lastName: "Skywalker",
        isActive: false
    });
});

Model Source : given the above MyView example, the template binding may reference a Backbone.Model data source directly through its context reference ($sourceName), such as:

```html
<div id="my-view" data-bind="template:$model">
    <template><%= firstName %> <%= lastName %></template>
</div>
```

When binding to a model source, all model attributes will be available to the template (this is equivalent to providing model.toJSON() to the template renderer). While this is a quick and easy binding method, it may not be the most efficient. The bound template will re-render in response to _all_ model changes, rather than just changes to specific attributes used in the template. In this scenario, our template would re-render in response to isActive changing, even though it's not included within the template.

text

read-write data-bind="text:modelAttribute"

Sets the element’s text content to the bound model attribute value. Uses the jQuery text method.

To enable a writeable binding, add the HTML5 contenteditable property to the element:

<span contenteditable="true" data-bind="text:yourName,events:['blur paste']">
    Select to edit your name.
</span>

toggle

read-only data-bind="toggle:modelAttribute"

Toggles the element’s display based on a loosely-typed assessment of the bound model attribute’s truthiness. Uses the jQuery toggle( [boolean] ) method.

value

read-write data-bind="value:modelAttribute"

Binds an input element’s (input, select, textarea) value to an underlying model attribute. The element will set its value to the bound model attribute upon change event triggers (see the events handler), and update its value when the underlying model attribute changes.