`{{#each}}`, `{{if}}`, `{{on}}`, and Components
Templates — Handlebars With Power-Ups
Ember templates are Handlebars with built-in helpers, modifiers, and angle-bracket component invocation — declarative HTML that is also reactive.
What you'll learn
- Use double-mustache interpolation
- Invoke components with the angle-bracket syntax
- Use built-in helpers like `{{if}}` and `{{each}}`
Ember’s templating language is Handlebars, extended with helpers, modifiers, and components. It is reactive: when a @tracked value changes, the parts of the DOM that read it re-render.
Interpolation
<h1>{{this.user.name}}</h1>
<p>You have {{this.cart.itemCount}} items.</p> Double mustaches read a value. this refers to the route’s controller or the component instance.
Conditionals & Loops
{{#if this.loading}}
<p>Loading…</p>
{{else if this.error}}
<p>Error: {{this.error.message}}</p>
{{else}}
<ul>
{{#each this.posts as |post index|}}
<li>{{index}}. {{post.title}}</li>
{{/each}}
</ul>
{{/if}} {{if}}, {{else if}}, {{each}} are built-in helpers — no imports.
Components & Events
<PostCard @post={{this.post}} @onSave={{this.save}} />
<button type="button" {{on "click" this.increment}}>
Increment
</button> Angle brackets invoke components. The {{on}} modifier attaches event listeners — it replaces the old action helper. Pass arguments to components with @argName={{value}}.
Built-in Helpers Worth Knowing
{{concat "a" "-" "b"}}— string join{{eq a b}}— equality{{fn this.save post}}— partially apply arguments{{hash key=value}}— build an object literal in a template