Attribute binding

Attribute binding in Aurelia is a powerful feature that allows you to dynamically bind data from your view model to any native HTML attribute within your templates. This enables real-time updates to element attributes such as classes, styles, src, alt, and other standard HTML attributes, enhancing the interactivity and responsiveness of your applications.

Basic Binding Syntax

The fundamental syntax for binding to attributes in Aurelia is simple and intuitive:

<div attribute-name.bind="value"></div>
  • attribute-name.bind="value": The binding declaration.

    • attribute-name: The target HTML attribute you want to bind to.

    • .bind: The binding command indicating a two-way binding by default.

    • value: The expression or property from the view model to bind.

You can bind to virtually any attribute listed in the HTML Attributes Reference.

Example: Binding the title Attribute

<!-- my-app.html -->
<div title.bind="tooltipText">Hover over me!</div>
// my-app.ts
export class MyApp {
  tooltipText = 'This is a tooltip';
}

Result: The div will have a title attribute with the value "This is a tooltip". Hovering over the div will display the tooltip.

When using an empty expression in a binding, such as attribute-name.bind or attribute-name.bind="", Aurelia automatically infers the expression based on the camelCase version of the target attribute. For example, attribute-name.bind="" is equivalent to attribute-name.bind="attributeName". This behavior applies to other binding commands as well:

  • .one-time

  • .to-view

  • .from-view

  • .two-way

  • .attr

Binding Techniques and Syntax

Aurelia provides multiple methods for attribute binding, each tailored for specific use cases and offering different levels of data flow control.

1. Interpolation Binding

Interpolation allows embedding dynamic values directly within strings. This is useful for concatenating strings with dynamic data.

Example: Binding the id Attribute Using Interpolation

Result: The h1 element will have an id attribute set to "main-heading".

2. Keyword Binding

Aurelia supports several binding keywords that define the direction and frequency of data flow between the view model and the view:

  • .one-time: Updates the view from the view model only once. Subsequent changes in the view model do not affect the view.

  • .to-view / .one-way: Continuously updates the view from the view model.

  • .from-view: Updates the view model based on changes in the view.

  • .two-way: Establishes a two-way data flow, keeping both the view and view model in sync.

  • .bind: Automatically determines the appropriate binding mode. Defaults to .two-way for form elements (e.g., input, textarea) and .to-view for most other elements.

Examples of Keyword Binding

Result: The input fields and links will reflect the bound properties with varying degrees of reactivity based on the binding keyword used.

3. Vue-style shorthand for .bind

If you are used to Vue or other template syntaxes, Aurelia ships with an attribute pattern that treats a leading colon as an alias for .bind. This allows you to write more compact markup without giving up any functionality.

The shorthand always creates a property binding (the same as attribute.bind). If you need a different binding mode, fall back to the explicit syntax (value.two-way, value.one-time, etc.). Event shorthands that start with @ are handled separately in the event binding guide.

3. Binding to Images

Binding image attributes such as src and alt ensures that images update dynamically based on the view model data.

Example: Dynamic Image Binding

Result: The img element will display the image from the specified src and use the provided alt text.

4. Disabling Elements

Dynamically enabling or disabling form elements enhances user interaction and form validation.

Example: Binding the disabled Attribute

Result: The Submit button starts as disabled, and the input field is enabled. Calling toggleButton() or toggleInput() will toggle their disabled states.

5. Binding innerHTML and textContent

Choose between innerHTML for rendering HTML content and textContent for rendering plain text to control how content is displayed within elements.

Example: Rendering HTML vs. Text

Result:

  • The first div will render the bold text as HTML.

  • The second div will display the HTML tags as plain text.

Advanced Binding Techniques

Explore more sophisticated binding scenarios to handle complex data interactions and ensure seamless attribute management.

0. Treating existing markup as a custom element with as-element

When outside systems dictate the tag name you must render (for example, a CMS that only allows <div> and <section>), you can still hydrate one of your custom elements by adding as-element="component-name" to any real DOM node. The compiler will instantiate component-name for that element while leaving the original tag in place.

  • Use as-element when you want the behavior of a custom element but must keep the original tag name for semantic or styling reasons.

  • Unlike <template as-custom-element="...">, this does not create a local element definition; it simply aliases an existing element instance.

  • The attribute can appear anywhere inside your markup except on the root <template> surrogate (putting it there triggers AUR0702).

This makes as-element a handy compatibility feature when integrating Aurelia components into environments with strict HTML requirements.

1. How Attribute Binding Works

Aurelia employs a mapping function to translate view model properties to corresponding HTML attributes. This typically involves converting kebab-case attribute names to camelCase property names. However, not all properties directly map to attributes, especially custom or non-standard attributes.

Example: Automatic Mapping

Result: The input element's value attribute is bound to the userName property. Changes in userName update the input value and vice versa.

Property vs. Attribute Targeting

By default, Aurelia bindings target DOM properties rather than HTML attributes. This distinction is important because:

  • Properties are JavaScript object properties on DOM elements (e.g., element.value)

  • Attributes are the HTML markup attributes (e.g., <input value="...">)

For most standard HTML attributes, this works seamlessly because browsers synchronize property and attribute values. However, for custom attributes or when you specifically need attribute targeting, use the .attr binding command or the attr binding behavior.

2. Using the .attr Binding Command

When automatic mapping fails or when dealing with non-standard attributes, use the .attr binding command to ensure proper attribute binding.

Example: Binding a Custom Attribute

Result: The input element will have a my-custom-attr attribute set to "Custom Attribute Value".

3. The attr Binding Behavior

The attr binding behavior is a powerful feature that forces any property binding to target the HTML attribute instead of the DOM property. This is especially useful for:

  • Custom attributes that don't have corresponding DOM properties

  • Data attributes (data-*)

  • ARIA attributes

  • SVG attributes

  • Cases where you need to ensure attribute-specific behavior

Example: Using the attr Binding Behavior

Result: All bindings will target their respective HTML attributes directly, ensuring proper DOM attribute manipulation.

4. Attribute Mapping and Custom Elements

Aurelia includes a built-in attribute mapper that handles common HTML attribute-to-property mappings automatically. For example:

  • maxlengthmaxLength

  • readonlyreadOnly

  • tabindextabIndex

  • contenteditablecontentEditable

You can extend this mapping for custom elements or third-party components:

5. Special Attribute Handling

Aurelia provides specialized handling for certain attributes:

Class Attributes

Style Attributes

Practical Use Cases

To better illustrate attribute bindings, here are several practical scenarios showcasing different binding techniques.

1. Dynamic Class Binding

Example: Toggling CSS Classes

Result: The div will have the class active when isActive is true and inactive when false. Calling toggleStatus() toggles the class.

2. Styling Elements Dynamically

Example: Binding Inline Styles

Result: The div's background color reflects the current value of bgColor. Invoking changeColor('coral') will update the background to coral.

3. Conditional Attribute Rendering

Example: Conditionally Setting the required Attribute

Result: The input field will be required based on the isEmailRequired property. Toggling this property will add or remove the required attribute.

Notes on Syntax

While attribute binding in Aurelia is versatile and robust, there are certain syntactical nuances and limitations to be aware of to prevent unexpected behavior.

  1. Expression Syntax Restrictions

    • No Chaining with ; or ,: Expressions within ${} cannot be chained using semicolons ; or commas ,. Each interpolation expression should represent a single, complete expression.

    • Restricted Primitives and Operators: Certain JavaScript primitives and operators cannot be used within interpolation expressions. These include:

      • Boolean

      • String

      • instanceof

      • typeof

      • Bitwise operators (except for the pipe | used with value converters)

    • Usage of Pipe |: The pipe character | is reserved exclusively for Aurelia's value converters within bindings and cannot be used as a bitwise operator.

  2. Attribute Targeting Syntax

    The presence of both .bind and .attr syntaxes can be confusing. Here's why both exist:

    • Property vs. Attribute Binding: .bind targets the DOM property, which is suitable for standard attributes that have corresponding DOM properties. However, for custom or non-standard attributes that do not have direct property mappings, .attr is necessary to bind directly to the attribute itself.

    • Example: Binding id Using Property and Attribute

      Result:

      • Using .bind, Aurelia binds to the id property of the input element.

      • Using .attr, Aurelia binds directly to the id attribute in the DOM.

  3. Choosing Between Interpolation and Keyword Binding

    Both interpolation and keyword binding can achieve similar outcomes. The choice between them often comes down to preference and specific use case requirements.

    • Performance and Features: There is no significant performance difference between the two. Both are equally efficient and offer similar capabilities.

    • Readability and Maintainability: Interpolation can be more readable for simple string concatenations, while keyword bindings offer more explicit control for complex bindings.

For complex transformations or formatting, consider using Aurelia's value converters instead of embedding extensive logic within interpolation expressions. This practice enhances code maintainability and separation of concerns.

Example: Using Value Converters for Formatting

Binding with a Value Converter

Result: Displays the totalPrice formatted as currency, e.g., "$199.99".

Troubleshooting and Common Issues

1. Binding Behavior Errors

Error: AUR9994 - Invalid Binding Type for 'attr' Binding Behavior

This error occurs when the attr binding behavior is used with non-property bindings:

2. Null and Undefined Values

When bound properties are null or undefined, attributes are removed from the DOM:

3. Custom Attribute Conflicts

When using .attr binding command, Aurelia bypasses custom attribute detection:

4. Boolean Attribute Handling

HTML boolean attributes (like disabled, checked, readonly) have special handling:

5. SVG Attributes

SVG attributes may require the attr binding behavior for proper functionality:

Performance Considerations

1. Binding Mode Selection

Choose the appropriate binding mode for optimal performance:

  • Use .one-time for static values that never change

  • Use .to-view for display-only data

  • Use .two-way only when bidirectional synchronization is needed

  • Use .from-view for write-only scenarios

2. Expression Complexity

Keep binding expressions simple for better performance:

3. Computed Properties

Use computed properties with proper dependencies for efficient updates:

Best Practices

1. Consistent Naming

Use consistent naming conventions for attributes and properties:

2. Type Safety

Leverage TypeScript for better development experience:

3. Error Boundaries

Handle potential errors in binding expressions:

4. Accessibility

Ensure proper accessibility attributes:

Summary

Attribute binding in Aurelia offers a flexible and powerful means to synchronize data between your view model and the DOM. By understanding and utilizing the various binding commands and techniques, you can create dynamic, responsive, and maintainable user interfaces. Always consider the specific needs of your project when choosing between different binding strategies, and leverage Aurelia's features to their fullest to enhance your application's interactivity and user experience.

Key takeaways:

  • Use the appropriate binding mode for your use case

  • Understand the difference between property and attribute targeting

  • Leverage the attr binding behavior for custom attributes

  • Handle null/undefined values gracefully

  • Consider performance implications of complex expressions

  • Follow accessibility best practices

  • Use TypeScript for better development experience

Last updated

Was this helpful?