This guide is a cheat sheet for using Ember.js. The examples are for Ember 7.3 and use the <template> tag. It doesn't cover everything, but it should get you started! PRs welcome at the GitHub repository.
For in-depth information, see The Ember Guides.
If you are looking for the Ember Octane vs Ember Classic Cheat Sheet, that is located here.
Nomenclature
§Template Tag
§
The <template> tag holds the template of a component in a .gjs or .gts file. The template can use every JavaScript value that is in scope, for example an import or a const. A file with only a <template> exports a template-only component. A <template> in a class body is the template of that class.
import Avatar from './avatar';
const greeting = 'Hello';
<template>
<Avatar />
{{greeting}}, {{@name}}!
</template>
References
Angle Brackets
§
The < and > surrounding the name of a component or element.
<SomeComponent />
↑ <br /> ↑
↑ ↑
Nested Components
§
A component in a subfolder of the components folder. In a .gjs or .gts file, import the component from its path and give it any name.
import SomeComponent from './nested/some-component';
<template>
<SomeComponent />
</template>
In a .hbs template, Ember finds components by name. There, a component in app/components/nested/some-component is invoked with :: between the folder names.
<Nested::SomeComponent />
Namespaced Components
§Alias for "Nested Components"
Arguments
§
Data that the caller passes to a component, a helper, or a modifier. The name of a component argument starts with @, for the caller and inside the component.
<SomeComponent @someArgument={{@anArgument}} />
Attributes
§Any HTML attribute, as available in the MDN list of HTML Attributes
<SomeComponent class="..." data-test style="..." />
<div class="...">
There are also splatted attributes or "splattributes", which represent forwarding all passed attributes from a calling context to the element which has ...attributes on it. Note that arguments are not included in ...attributes.
In this example below, if this div were to represent the template for SomeComponent above, the class, data-test, and style attributes would be applied to the div.
<div ...attributes></div>
this
§
this is the instance of the class that contains the <template>. A template-only component has no class, so there this is undefined. In a route template in a .hbs file, this is the instance of the controller.
import Component from '@glimmer/component';
export default class Greeting extends Component {
greeting = 'Hello';
<template>
{{this.greeting}}, {{@name}}!
</template>
}
Block
§A block is a nested scope that has local variables that are not available outside of the block. Like in JavaScript, variables defined outside of the block can still be accessed. Unlike handlebars, there is no implicit scope.
A block can be defined with curly braces denoted by # to signify the start of the block, and / to signify the end of the block.
{{#let (array 1 2 3) as |threeItems|}}
{{threeItems}}
{{/let}}
A block can be defined with component invocations, much like the curly block, where the available new local variables are defined between the as pipes, |...|.
<MyComponent as |a b|>
{{a}} {{b}}
</MyComponent>
Note that inside MyComponent there must be a {{yield}} in order for the block to render.
Named Block
§
A block with a name. The caller writes a named block as <:name>...</:name> inside the component invocation. A component can receive many named blocks, and it decides where each block renders. A block without a name is the block with the name default.
import Card from './card';
<template>
<Card>
<:header>Ember</:header>
<:body>A framework for ambitious web developers.</:body>
</Card>
</template>
yield
§
yield renders the block that the caller passed to the component. Each value after yield becomes a block parameter. The caller receives the block parameters between the pipes of as |...|. Use to="name" to render a named block.
const Article = <template>
<article>
{{yield @title}}
</article>
</template>;
<template>
<Article @title="Hello" as |title|>
<h1>{{title}}</h1>
</Article>
</template>