An Angular component defines a portion of an application's interface. It pairs a TypeScript class decorated with @Component and an HTML template. The decorator's selector identifies where the component appears; templateUrl identifies the template file. Template expressions use the class's properties and methods to generate content. section 18.4
Listing 18.13 The contents of the productItem.component.ts file in the src/app folder
import { Component, Input, Output, EventEmitter } from "@angular/core";
import { Product } from './data/entities';
export type productSelection = {
product: Product,
quantity: number
}
@Component({
selector: "product-item",
templateUrl: "./productItem.component.html"
})
export class ProductItem {
quantity: number = 1;
@Input()
product: Product = {
id: 0, name: "", description: "", category: "", price: 0
}
@Output()
addToCart = new EventEmitter<productSelection>();
handleAddToCart() {
this.addToCart.emit({ product: this.product,
quantity: Number(this.quantity)});
}
}
The product-item class receives a Product through @Input and emits an addToCart event through @Output. Its selector and templateUrl connect the class to an element and a separate HTML file. section 18.4
A template can display `{{ product.price.toFixed(2) }}`, call `handleAddToCart()` with `(click)`, and keep a selection connected to `quantity` with `[(ngModel)]`. These expressions and handlers refer to the component instance. section 18.4
Connect a header to its parent
In a parent template, `<header [order]="dataSource.order" (submit)="handleSubmit()"></header>` supplies an order to the header's @Input property and handles its @Output event. The header displays the order count and total; its button emits `submit`. The parent can likewise render product-item elements with `*ngFor` and handle their addToCart events. section 18.4.2 section 18.4.3
Listing 18.20 The contents of the productList.component.html file in the src/app folder
<header [order]="dataSource.order" (submit)="handleSubmit()"></header>
<div class="container-fluid">
<div class="row">
<div class="col-3 p-2">
<category-list [selected]="selectedCategory"
[categories]="categories"
(selectCategory)="handleCategorySelect($event)">
</category-list>
</div>
<div class="col-9 p-2">
<product-item *ngFor="let p of products" [product]="p"
(addToCart)="handleAdd($event)"></product-item>
</div>
</div>
</div>
The product-list template combines header, category-list, and repeated product-item elements, passing values down and receiving events back. section 18.4.3
Declare the component classes in the application's NgModule. When Angular encounters a registered selector such as `<product-list>`, it creates that component, renders its template, and resolves component elements within it. In this product interface, filtering and adding products work; Submit Order initially only writes to the console. section 18.5 section 18.4.3
