Components

Angular Docs

A component controls a patch of screen called a view.

Component's application logic is defined inside a class. The class interacts with the view through an API of properties and methods

Component Tree

Component is just a class...


	export class BookDetailsComponent implements OnInit {
	  currentBook = new Book();

	  ngOnInit(): void {
		this.currentBook.author = 'John Example';
		this.currentBook.title = 'Angular in a nutshell';
	  }
	}
				

...which has an API for the view


	export class BookDetailsComponent implements OnInit {
	  currentBook = new Book();

	  ngOnInit(): void {
		this.currentBook.author = 'John Example';
		this.currentBook.title = 'Angular in a nutshell';
	  }
	}
				

...and can implement hooks


	export class BookDetailsComponent implements OnInit {
	  currentBook = new Book();

	  ngOnInit(): void {
		this.currentBook.author = 'John Example';
		this.currentBook.title = 'Angular in a nutshell';
	  }
	}
				

Angular creates, updates, and destroys components as the user moves through the application. Your app can take action at each moment in this lifecycle through optional lifecycle hooks

Examples for lifecycle hooks:
Constructor, NgOnInit & NgOnDestroy

Angular Docs

Component template is regular HTML...


	<div>
	  <label>Author:</label> <span>{{currentBook.author}}</span>
	</div>
	<div>
	  <label>Title:</label> <span>{{currentBook.title}}</span>
	</div>
				

...with Angular's template syntax


	<div>
	  <label>Author:</label> <span>{{currentBook.author}}</span>
	</div>
	<div>
	  <label>Title:</label> <span>{{currentBook.title}}</span>
	</div>
				

A template is a form of HTML that tells Angular how to render the component.

A template looks like regular HTML with Angularized markup which uses Angular's template syntax.

Component Metadata tells Angular where to get the major building blocks you specify for the component.


	@Component({
	  selector: 'app-book-details',
	  template:
		`<div>
		   <label>Author:</label> <span>{{currentBook.author}}</span>
		 </div>
		 <div>
		   <label>Title:</label> <span>{{currentBook.title}}</span>
		 </div>`
	})
	export class BookDetailsComponent implements OnInit {
	...
	}
				

selector tells Angular to create and insert an instance of this component where it finds a <app-book-details> tag in parent HTML


	@Component({
	  selector: 'app-book-details',
	  template:
		`<div>
		   <label>Author:</label> <span>{{currentBook.author}}</span>
		 </div>
		 <div>
		   <label>Title:</label> <span>{{currentBook.title}}</span>
		 </div>`
	})
	export class BookDetailsComponent implements OnInit {
	...
	}
				

Templates can be inlined, e.g. using ES2015 template literals (multi line strings marked with backticks) or ...


	@Component({
	  selector: 'app-book-details',
	  template:
		`<div>
		   <label>Author:</label> <span>{{currentBook.author}}</span>
		 </div>
		 <div>
		   <label>Title:</label> <span>{{currentBook.title}}</span>
		 </div>`
	})
	export class BookDetailsComponent implements OnInit {
	...
	}
				

...extracted to a separate file and imported using file path


	@Component({
	  selector: 'app-book-details',
	  templateUrl: './book-details.component.html'
	})
	export class BookDetailsComponent implements OnInit {
	...
	}
				

Components are styled using a separate css file that is only applied to the component and not to subordinate components.


	@Component({
	  selector: 'app-book-details',
	  template: ...,
	  styleUrls: ['./book-details.component.css']
	})
	export class BookDetailsComponent implements OnInit {
	...
	}
				

In TypeScript metadata can be attached to the component class by using a decorator.

Importing and using components

Angular supports two ways of making a component available to other components:
as a standalone component or in an NgModule.


The Angular team recommends using standalone components for all new development.


Angular Docs

Import TypeScript sources

 
			import { Component } from '@angular/core'; 
			import { ProfilePhoto } from './profile-photo.component';

			@Component({
			  standalone: true,
			  imports: [ProfilePhoto],
			  template: ``
			})
			export class UserProfile { }
				

TypeScript Docs

Define a Standalone Component

 
			import { Component } from '@angular/core'; 
			import { ProfilePhoto } from './profile-photo.component';

			@Component({
			  standalone: true,
			  imports: [ProfilePhoto],
			  template: ``
			})
			export class UserProfile { }
				

Angular Docs

Import Standalone Components

 
			import { Component } from '@angular/core'; 
			import { ProfilePhoto } from './profile-photo.component';

			@Component({
			  standalone: true,
			  imports: [ProfilePhoto],
			  template: ``
			})
			export class UserProfile { }
				

Angular Docs

Import Modules

 
				import { Component } from '@angular/core';
				import { ReactiveFormsModule } from '@angular/forms';
				
				@Component({
				  standalone: true,
				  selector: 'user-profile',
				  template: ``,
				  imports: [ReactiveFormsModule]
				})
				export class UserProfile {
				  profileForm = new FormGroup({
					name: new FormControl('')
				  });
				}
				  

Simple module

An Angular module is a class decorated with @NgModule metadata.



@NgModule({
// applications modules, angular modules, libraries, etc.
imports: [],

// components, directives and pipes which should be made public
// 're-export' imported modules
exports: [],

// components, directives and pipes which belong to the module
// -> they can only be used in components templates inside this modules
declarations: [],

// services which should be useable by child modules and components
// details on providers and injection are in the services presentation
providers: []
})
export class TestModule { }

Angular Docs

... example

@NgModule({
  imports: [CommonModule],
  exports: [CommonModule, BookListComponent],
  declarations: [BookListComponent, BookDetailComponent],
  providers: [BookService],
})
export class BookModule { }
  • Angular Common module is imported - e.g. *ngIf can be used in templates
  • Common module is exported - so a module importing BookModule can use Common without importing it
  • BookListComponent can be used inside templates in modules importing BookModule - 'it's public'
  • BookListComponent and BookDetailComponent are declared and can therefore be used inside modules templates - good practice if for instance BookDetailComponent is part of BookListComponent and should never be used alone
  • BookService is provided for all components within BookModule and child modules

Application Structure

Core and Shared Module

  • This modules were Angular best practices
  • CoreModule is only imported in AppModule and it has single use components - e.g. NavigationComponent, FooterComponent, etc. to be used inside AppComponents template
  • SharedModule has common components, directives and pipes. Imported by multiple modules - e.g. SpinnerComponent, ModalComponent
  • The use of standalone components does not mean you cannot structure your components!

Application Structure Example with Modules

Old Angular.io Docs

Structure with Standalone Components

New Angular.dev Docs

Summary

  • Angular Components
    • represent patches of the screen
    • are just classes with @Component decorator
    • has building blocks for logic, template and style
  • Importing and using components
    • by importing it in TypeScript
    • by importing it in a Standalone Component or Module
    • within a module by declaring it
  • Structuring Application

Live Code Examples & Backup slides below

Live Code Examples

Backup slides

Following slides are not subject of the lecture.
Ask trainers in case of questions.

Component CSS Styles

Their selectors only apply within the template of that component

Their class names and selectors do not collide with ones used elsewhere in the application

Component's styles cannot be changed by changes to styles elsewhere in the application

Pseudo selectors, e.g. :host, from shadow DOM style scoping are available


	:host {
	  display: block;
	  font-size: x-large;
	}
	:host label {
	  font-weight: bold;
	}
				
Angular Docs

Standalone components Definition

  • Introduced with Angular 14.
  • Standalone components reduce the complexity of NgModules, providing a more lightweight and modular approach to building Angular applications.
  • Standalone components can directly import other components, directives, and pipes used in their templates without the need for NgModules.

Benefits of Direct Importing

  • Eliminates the need for NgModules to declare and import components.
  • Improves code clarity and maintainability.
  • Provides finer control over each component's dependencies.

Future of Angular development

  • The Angular team recommends using standalone components for all new development.
  • Starting with Angular 17, creating an Angular application with ng new will generate a standalone application by default.

Starting with Angular 19 standalone: true will be default.


					@Component({
					  imports: [ProfilePhoto],
					  template: ``
					})
					export class UserProfile { }
					

Add standalone: false to existing ngModule components so they continue to work.


					  @Component({
						standalone: false,
						template: ``
					  })
					  export class UserProfile { }
					  

Modules Definition

Angular modules consolidate components, directives and pipes into cohesive blocks of functionality, each focused on a feature area, application business domain, workflow, or common collection of utilities.

Application Start with Modules (1/2)

AppModule is the top level Module which gets bootstrapped

import { NgModule }      from '@angular/core';
	import { BrowserModule } from '@angular/platform-browser';
	import { AppComponent }  from './app.component';

	@NgModule({
	  imports:      [ BrowserModule ],
	  declarations: [ AppComponent ],
	  // top level component to insert into index.html
	  bootstrap:    [ AppComponent ]
	})
	export class AppModule { }
app.module.ts

Switch to standalone bootstrapping API

Application Start with Modules (2/2)


	import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
	import { AppModule }              from './app.module';

	platformBrowserDynamic().bootstrapModule(AppModule);
main.ts
<my-app>Loading ...</my-app>
index.html
import { Component } from '@angular/core';

	@Component({
	  selector: 'my-app',
	})
	export class AppComponent { }
app.component.ts