Angular Components
Components are the main building blocks of an Angular app. Each one controls a part of the screen.
Generating a Component
Use the CLI to create a component:
Example
ng generate component course-cardCREATE src/app/course-card/course-card.css CREATE src/app/course-card/course-card.html CREATE src/app/course-card/course-card.spec.ts CREATE src/app/course-card/course-card.ts
The .spec.ts file is for tests. You can ignore it for now.
Parts of a Component
Example
import { Component } from "@angular/core";
@Component({
selector: "app-course-card",
templateUrl: "./course-card.html",
styleUrl: "./course-card.css",
})
export class CourseCard {
title = "Web Development";
months = 6;
}| Property | Meaning |
|---|---|
selector | The tag name used in other templates: <app-course-card /> |
templateUrl | The HTML file for this component |
template | Inline HTML instead of a separate file |
styleUrl | The CSS file; styles apply only to this component |
imports | Other components and directives this template uses |
course-card.html:
Example
<div class="card">
<h3>{{ title }}</h3>
<p>{{ months }} months</p>
</div>Using a Component in Another
Modern components are standalone. To use one inside another, add it to the imports array:
Example
import { Component } from "@angular/core";
import { CourseCard } from "./course-card/course-card";
@Component({
selector: "app-root",
imports: [CourseCard],
template: `
<h1>Our Courses</h1>
<app-course-card />
<app-course-card />
`,
})
export class App {}If you forget the import, Angular shows an error like "'app-course-card' is not a known element".
Inputs: Passing Data In
To give each card different data, declare inputs with the input() function:
Example
import { Component, input } from "@angular/core";
@Component({
selector: "app-course-card",
template: `
<div class="card">
<h3>{{ title() }}</h3>
<p>{{ months() }} months</p>
</div>
`,
})
export class CourseCard {
title = input.required<string>();
months = input(3);
}input() returns a signal, so you read it by calling it: title(). input.required means the parent must give a value; input(3) has a default of 3.
The parent passes values with square brackets for expressions, or plain attributes for strings:
Example
<app-course-card title="Web Development" [months]="6" />
<app-course-card title="Graphic Designing" />Web Development 6 months Graphic Designing 3 months
Outputs: Sending Events Out
A child tells its parent that something happened with output():
Example
import { Component, input, output } from "@angular/core";
@Component({
selector: "app-enrol-button",
template: `<button (click)="enrol.emit(course())">Enrol in {{ course() }}</button>`,
})
export class EnrolButton {
course = input.required<string>();
enrol = output<string>();
}The parent listens with round brackets. $event holds the emitted value:
Example
@Component({
selector: "app-root",
imports: [EnrolButton],
template: `
<app-enrol-button course="AI" (enrol)="onEnrol($event)" />
<p>{{ message }}</p>
`,
})
export class App {
message = "";
onEnrol(course: string) {
this.message = `Ayesha enrolled in ${course}`;
}
}(after click) Ayesha enrolled in AI
| Direction | Function | Parent syntax |
|---|---|---|
| Parent to child | input() | [name]="value" |
| Child to parent | output() | (name)="handler($event)" |
Older code uses @Input() and @Output() decorators with EventEmitter. They still work, but the input() and output() functions are the modern choice.
Component Styles
Styles in a component's CSS file apply only to that component. A .card rule in course-card.css will not affect other parts of the app. Global styles go in src/styles.css.
Exercise
Exercise
Where do you list a child component so a standalone component's template can use it?
