LogoLogo
HomeDiscourseBlogDiscord
  • Introduction
  • Introduction
    • Quick start
    • Aurelia for new developers
    • Hello world
      • Creating your first app
      • Your first component - part 1: the view model
      • Your first component - part 2: the view
      • Running our app
      • Next steps
  • Templates
    • Template Syntax
      • Attribute binding
      • Event binding
      • Text interpolation
      • Template promises
      • Template references
      • Template variables
      • Globals
    • Custom attributes
    • Value converters (pipes)
    • Binding behaviors
    • Form Inputs
    • CSS classes and styling
    • Conditional Rendering
    • List Rendering
    • Lambda Expressions
    • Local templates (inline templates)
    • SVG
  • Components
    • Component basics
    • Component lifecycles
    • Bindable properties
    • Styling components
    • Slotted content
    • Scope and context
    • CustomElement API
    • Template compilation
      • processContent
      • Extending templating syntax
      • Modifying template parsing with AttributePattern
      • Extending binding language
      • Using the template compiler
      • Attribute mapping
  • Getting to know Aurelia
    • Routing
      • @aurelia/router
        • Getting Started
        • Creating Routes
        • Routing Lifecycle
        • Viewports
        • Navigating
        • Route hooks
        • Router animation
        • Route Events
        • Router Tutorial
        • Router Recipes
      • @aurelia/router-lite
        • Getting started
        • Router configuration
        • Configuring routes
        • Viewports
        • Navigating
        • Lifecycle hooks
        • Router hooks
        • Router events
        • Navigation model
        • Current route
        • Transition plan
    • App configuration and startup
    • Enhance
    • Template controllers
    • Understanding synchronous binding
    • Dynamic composition
    • Portalling elements
    • Observation
      • Observing property changes with @observable
      • Effect observation
      • HTML observation
      • Using observerLocator
    • Watching data
    • Dependency injection (DI)
    • App Tasks
    • Task Queue
    • Event Aggregator
  • Developer Guides
    • Animation
    • Testing
      • Overview
      • Testing attributes
      • Testing components
      • Testing value converters
      • Working with the fluent API
      • Stubs, mocks & spies
    • Logging
    • Building plugins
    • Web Components
    • UI virtualization
    • Errors
      • Kernel Errors
      • Template Compiler Errors
      • Dialog Errors
      • Runtime HTML Errors
    • Bundlers
    • Recipes
      • Apollo GraphQL integration
      • Auth0 integration
      • Containerizing Aurelia apps with Docker
      • Cordova/Phonegap integration
      • CSS-in-JS with Emotion
      • DOM style injection
      • Firebase integration
      • Markdown integration
      • Multi root
      • Progress Web Apps (PWA's)
      • Securing an app
      • SignalR integration
      • Strongly-typed templates
      • TailwindCSS integration
      • WebSockets Integration
      • Web Workers Integration
    • Playground
      • Binding & Templating
      • Custom Attributes
        • Binding to Element Size
      • Integration
        • Microsoft FAST
        • Ionic
    • Migrating to Aurelia 2
      • For plugin authors
      • Side-by-side comparison
    • Cheat Sheet
  • Aurelia Packages
    • Validation
      • Validation Tutorial
      • Plugin Configuration
      • Defining & Customizing Rules
      • Architecture
      • Tagging Rules
      • Model Based Validation
      • Validation Controller
      • Validate Binding Behavior
      • Displaying Errors
      • I18n Internationalization
      • Migration Guide & Breaking Changes
    • i18n Internationalization
    • Fetch Client
      • Overview
      • Setup and Configuration
      • Response types
      • Working with forms
      • Intercepting responses & requests
      • Advanced
    • Event Aggregator
    • State
    • Store
      • Configuration and Setup
      • Middleware
    • Dialog
  • Tutorials
    • Building a ChatGPT inspired app
    • Building a realtime cryptocurrency price tracker
    • Building a todo application
    • Building a weather application
    • Building a widget-based dashboard
    • React inside Aurelia
    • Svelte inside Aurelia
    • Synthetic view
    • Vue inside Aurelia
  • Community Contribution
    • Joining the community
    • Code of conduct
    • Contributor guide
    • Building and testing aurelia
    • Writing documentation
    • Translating documentation
Powered by GitBook
On this page
  • Quick Reference
  • Using if.bind
  • Basic Usage
  • If/Else Structures
  • Caching Behavior
  • Using show.bind
  • Basic Usage
  • When to Use show.bind vs if.bind
  • Using switch.bind
  • Basic Usage
  • Grouping Cases
  • Fall-Through Behavior
  • Advanced Techniques
  • Dynamic Switch Expressions
  • Conditional Slot Projection
  • Nested Switches
  • Performance Guidelines
  • Choosing the Right Directive
  • Optimization Tips
  • Important Restrictions
  • Case Usage Rules
  • Default Case Placement

Was this helpful?

Export as PDF
  1. Templates

Conditional Rendering

Learn about the various methods for conditionally rendering content in Aurelia 2, with detailed explanations and examples.

Conditional rendering allows you to dynamically show or hide parts of your view based on your application's state. Aurelia 2 provides three primary directives for conditional rendering, each suited for different scenarios.

Quick Reference

Directive
Use Case
DOM Behavior
Performance

if.bind

Simple true/false conditions

Adds/removes elements

Best for infrequent changes

show.bind

Toggle visibility

Hides/shows elements

Best for frequent changes

switch.bind

Multiple conditions

Adds/removes elements

Best for enum-like values

Using if.bind

The if.bind directive conditionally adds or removes elements from the DOM based on a boolean expression. When the expression is false, Aurelia completely removes the element and its descendants, cleaning up resources, events, and custom elements.

Basic Usage

<div if.bind="isLoading">Loading...</div>
<div if.bind="user.isAuthenticated">Welcome back, ${user.name}!</div>

If/Else Structures

Use else immediately after an if.bind element to create branching logic:

<div if.bind="user.isAuthenticated">
  Welcome back, ${user.name}!
</div>
<div else>
  Please log in to continue.
</div>

Caching Behavior

By default, if.bind caches views and view models for performance. Disable caching when you need fresh instances:

<custom-element if="value.bind: canShow; cache: false"></custom-element>

When to Use: Use if.bind when elements change infrequently and you want to completely remove them from the DOM to save memory and improve performance.

Using show.bind

The show.bind directive toggles element visibility without removing them from the DOM. This is equivalent to setting display: none in CSS.

Basic Usage

<div show.bind="isDataLoaded">Data loaded successfully!</div>
<div show.bind="!isLoading">Content is ready</div>

When to Use show.bind vs if.bind

<!-- Use show.bind for frequent toggles -->
<div show.bind="isExpanded">
  <expensive-component></expensive-component>
</div>

<!-- Use if.bind for infrequent changes -->
<admin-panel if.bind="user.isAdmin"></admin-panel>

When to Use: Use show.bind when you need to frequently toggle visibility and want to preserve element state, bindings, and avoid re-initialization costs.

Using switch.bind

The switch.bind directive handles multiple conditions elegantly, similar to a JavaScript switch statement. It's ideal for enum values or when you have several mutually exclusive conditions.

Basic Usage

// Status.ts
enum OrderStatus {
  Received   = 'received',
  Processing = 'processing',
  Dispatched = 'dispatched',
  Delivered  = 'delivered'
}
<!-- order-status.html -->
<template switch.bind="orderStatus">
  <span case="received">Order received</span>
  <span case="processing">Processing your order</span>
  <span case="dispatched">On the way</span>
  <span case="delivered">Delivered</span>
  <span default-case>Unknown status</span>
</template>

Grouping Cases

Handle multiple values with a single case:

<template switch.bind="orderStatus">
  <span case.bind="['received', 'processing']">
    Order is being processed
  </span>
  <span case="dispatched">On the way</span>
  <span case="delivered">Delivered</span>
</template>

Fall-Through Behavior

Enable fall-through to show multiple cases:

<template switch.bind="orderStatus">
  <span case="received" fall-through="true">Order received</span>
  <span case="processing">Processing your order</span>
</template>

Fall-through is false by default. Set fall-through="true" or fall-through.bind="true" to enable it.

Advanced Techniques

Dynamic Switch Expressions

Use computed expressions with switch.bind:

<template repeat.for="num of numbers">
  <template switch.bind="true">
    <span case.bind="num % 15 === 0">FizzBuzz</span>
    <span case.bind="num % 3 === 0">Fizz</span>
    <span case.bind="num % 5 === 0">Buzz</span>
    <span default-case>${num}</span>
  </template>
</template>

Conditional Slot Projection

Combine switch.bind with slots for dynamic content projection:

<template as-custom-element="status-card">
  <au-slot name="content"></au-slot>
</template>

<status-card>
  <template au-slot="content" switch.bind="status">
    <div case="loading">Loading...</div>
    <div case="error">Something went wrong</div>
    <div case="success">Operation completed</div>
  </template>
</status-card>

Nested Switches

Handle complex conditional logic with nested switches:

<template switch.bind="userRole">
  <div case="admin">
    <template switch.bind="adminSection">
      <admin-users case="users"></admin-users>
      <admin-settings case="settings"></admin-settings>
      <admin-dashboard default-case></admin-dashboard>
    </template>
  </div>
  <user-dashboard case="user"></user-dashboard>
  <guest-welcome default-case></guest-welcome>
</template>

Performance Guidelines

Choosing the Right Directive

  • Frequent toggles: Use show.bind to avoid DOM manipulation overhead

  • Infrequent changes: Use if.bind to remove elements and save memory

  • Multiple conditions: Use switch.bind for cleaner, more maintainable code

Optimization Tips

<!-- Good: Group related conditions -->
<template switch.bind="appState">
  <loading-screen case="loading"></loading-screen>
  <error-screen case="error"></error-screen>
  <main-content case="ready"></main-content>
</template>

<!-- Avoid: Multiple separate if statements -->
<loading-screen if.bind="appState === 'loading'"></loading-screen>
<error-screen if.bind="appState === 'error'"></error-screen>
<main-content if.bind="appState === 'ready'"></main-content>

Important Restrictions

Case Usage Rules

The case attribute must be a direct child of switch.bind:

<!-- ✅ Correct -->
<template switch.bind="status">
  <span case="active">Active</span>
</template>

<!-- ❌ Incorrect: case not direct child -->
<template switch.bind="status">
  <div if.bind="someCondition">
    <span case="active">Active</span>
  </div>
</template>

Default Case Placement

Place default-case as the last option for best practices:

<template switch.bind="status">
  <span case="received">Received</span>
  <span case="processing">Processing</span>
  <span default-case>Unknown</span> <!-- Last -->
</template>
PreviousCSS classes and stylingNextList Rendering

Last updated 4 days ago

Was this helpful?