Skip to content

Architecture

The architecture of an angular application is based on some basic assumptions and concepts. The basic building blocks are modules that provide context for compiling the components. The application always has at least a main module that allows the basic component to be loaded, and usually has many other functional modules.

Components define views, which are sets of screen elements that Angular can render and modify according to the application logic and data.

Components use services that provide specific functionality not directly related to views. These services are injected into components as dependencies, making the resulting code modular and reusable.

Modules, components, and services are classes that use decorators. Decorators set the appropriate class type and provide metadata that tells Angular how to use it.

Design pattern

To this day, there are disputes over which pattern Angular is written according to. Its closest to MVC and MVVM, which is very similar to the former.

MVC

  • Model, View, Controller
  • Basically one-way communication
  • Poor interactivity

MVVM

  • Model, View, ViewModel
  • Two-way communication
  • Rich interactivity

Don't fall for the abbreviation of the MVVM pattern, i.e. the omission of the letter C. The controllers are still there. They must be. Nothing has been removed from MVC. We only add one thing: firmness, data stored in the client's cache. This data, basically a cache on the client, is now called "ViewModel". This is what allows for rich interactivity.

Metadata

Metadata is defined as data information. In Angular, metadata is used to determine how the framework processes a class. The order of the metadata is not important.

The class decorator is used to define metadata about a class. For example, each class to which the @ Component decorator is attached is called a component.

@Component({ 
  selector: 'my-app', 
  templateUrl: 'app/app.component.html' 
}) 

Modules

In general, module is used to group related classes together to achieve a given functionality. In Angular, a module is a mechanism that groups related components, directives, pipes, services, etc.

The modules allow the individual parts of the system to be logically separated from each other, so that they do not influence each other.

Each browser application module must import BrowserModule inside the decorator @NgModule({}).

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

@NgModule({
  imports:      [ BrowserModule ],
  providers:    [ Logger ],
  declarations: [ AppComponent ],
  exports:      [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }
  • declarations: components, directives, and pipes that belong to this module.
  • exports: a subset of declarations that should appear in the component templates of other modules.
  • imports: other modules whose exportable classes are needed in the component templates declared in this module.
  • providers: providers of the services this module contributes to the global site pool; become available in all parts of the application.
  • bootstrap: the main application view, called the root component, which handles all other application views.

Components

Components play a key role in Angular. Every Angular application must have at least one component. A component represents a specific part of the user interface (UI).

Each component contains a selector that represents the HTML code associated with that component.

To make a class a component, add the decorator @Component({}) above its definition. This decorator must contain a field with view information.

import { Component } from '@angular/core';

@Component({
  selector: 'app-hello',
  templateUrl: './hello.component.html',
  styleUrls: ['./hello.component.css']
})
export class HelloComponent {
  title = 'My first app!';
}
  • selector: name of the tag that will be responsible for representing the component.
  • template: The template HTML for the component.
  • templateUrl: path to the template file with HTML for the component.
  • style: CSS code for the component.
  • styleUrls: path to the CSS style sheet file.

Templates

Template contains the HTML code to be displayed on the user's screen. In Angular, the template contains HTML elements and custom tags and expressions.

Angular-specific expressions and custom tags are replaced with the associated HTML code before the template content is displayed.

Template = HTML + Custom Tags + Angular Expressions

<h2>Products</h2>

<div *ngFor="let product of products">

  <h3>
    <a [title]="product.name + ' details'">
      {{ product.name }}
    </a>
  </h3>

  <p *ngIf="product.description">
    Description: {{ product.description }}
  </p>

  <button (click)="share()">
    Share
  </button>

</div>

The custom tags, expressions and attributes used in the template are explained here.

Data binding

Data binding is one of the basic concepts in Angular and allows the communication between the component and the [DOM] (../../HTML_CSS_JS/JavaScript/dom_model.md). Whenever the variable changes, the view is updated in the DOM to reflect the new changes. There are four forms of data binding and they differ in the way they flow.

String Interpolation

[One-way data binding type] (project_structure.md#srcappappcomponenthtml), where the text is between double curly braces. Angular replaces the text between the parentheses with the appropriate component property (variable or method).

<p>Hello, my name is {{ name }}!</p>

Property Binding

Allows you to bind an attribute of an HTML element. Between the square brackets [] the name of the property that is to be associated with the element is written. As with String Interpolation, it is a one-way mechanism.

<img [src]="image.url" [alt]="image.alt">

Event Binding

It allows to update/send the value/information of a given variable from the presentation layer (template) to the component (communication child -> parent). In the DOM, elements can react to various events, and via Event Binding they can bind to a function which will be run when the event is broadcast. An example event is clicking a button.

<button (click)="clickHandler()">Click Me</button>

Two-Way Data Binding

Bidirectional data binding is a combination of both property binding and event binding and is a continuous synchronization of data from view to component and from component to view, i.e. changes made to component data should synchronize with the view and immediately update the corresponding component model with the view data. Two-way data binding can be easily achieved with ngModel.

<input type="text" [(ngModel)]="firstName">

Life cycles

Each component has its own life cycle which consists of several different stages it goes through. Each stage is called a lifecycle hook. They differ in time and the reason why they are performed. Importantly, the attachment points are performed in the right order. Component class constructor code executes before calling any component lifecycle method.

There are 8 different hooks, but only those related to the component itself will be shown here.

ngOnChanges

It is executed each time the component's input value has changed. This hook has a data map that contains the current and previous value of the changed value.

ngOnInit

Executes after the component is initialized. This point is basically only called after ngOnChanges() and mainly used for data initialization in the component.

ngDoCheck

This point is triggered every time the component's input properties are checked. This method allows you to implement your own change detection and data validation logic.

ngOnDestroy

This method is performed just before the component is destroyed. This point is very useful for unsubscribing from observing objects to avoid memory leaks.

Services

In Angular, services are single objects that are run only once in the lifetime of the application. They contain data that must be shared throughout the application. They are mainly used as interfaces to external systems (mostly internet).

The main goal of the website is to organize and share business logic and data with different components of Angular application.

interface Post {
  id: number;
  title: string;
  body: string;
}

@Injectable({
  providedIn: 'root'
})
export class PlaceholderService {
  constructor(private http:HttpClient) { }

  getPosts():Observable<Post[]> {
    return this.http.get('https://jsonplaceholder.typicode.com/posts');
  }

  getPost(id:number):Observable<Post> {
    return this.http.get(`https://jsonplaceholder.typicode.com/posts/${id}`);
  }
}

The @Injectable({}) decorator makes the class injectable into a constructor, such as a component. The field provideIn: 'root' allows you to skip the step of specifying a service in the providers property of the @NgModule({}) decorator.