Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Expert Angular

You're reading from   Expert Angular Build deep understanding of Angular to set you apart from the developer crowd

Arrow left icon
Product type Paperback
Published in Jul 2017
Publisher Packt
ISBN-13 9781785880230
Length 454 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Authors (4):
Arrow left icon
Sridhar Rao Chivukula Sridhar Rao Chivukula
Author Profile Icon Sridhar Rao Chivukula
Sridhar Rao Chivukula
Mathieu Nayrolles Mathieu Nayrolles
Author Profile Icon Mathieu Nayrolles
Mathieu Nayrolles
Alexandru Vasile Pop Alexandru Vasile Pop
Author Profile Icon Alexandru Vasile Pop
Alexandru Vasile Pop
Rajesh Gunasundaram Rajesh Gunasundaram
Author Profile Icon Rajesh Gunasundaram
Rajesh Gunasundaram
Arrow right icon
View More author details
Toc

Table of Contents (18) Chapters Close

Preface 1. Architectural Overview and Building a Simple App in Angular 2. Migrating AngularJS App to Angular App FREE CHAPTER 3. Using Angular CLI to Generate Angular Apps with Best Practices 4. Working with Components 5. Implementing Angular Routing and Navigation 6. Creating Directives and Implementing Change Detection 7. Asynchronous Programming Using Observables 8. Template and Data Binding Syntax 9. Advanced Forms in Angular 10. Material Design in Angular 11. Implementing Angular Pipes 12. Implementing Angular Services 13. Applying Dependency Injection 14. Handling Angular Animation 15. Integrating Bootstrap with Angular Application 16. Testing Angular Apps Using Jasmine and Protractor Frameworks 17. Design Patterns in Angular

Angular architecture

Before we discuss architecture, let's see what's new in Angular. The primary focus of Angular is mobiles, as it is important to consider the performance and loading time of the application on a mobile phone. Many modules are decoupled from the Angular core, leaving only the modules that are definitely core; removing unwanted modules from Angular core leads to better performance.

Angular targets ES6 and leverages TypeScript as a development script language that enables compile time checks for types, rather than at runtime. TypeScript provides additional information about classes when instantiating them by annotating metadata to the classes. You can also use ES5 and Dart as the development language. There is an improved version of Dependency Injection that supports child injectors and instance scope. Router was rewritten completely and the component router was introduced. The Component Directive, the Decorator Directive, and the Template Directive are supported in Angular. The $scope has been completely removed from Angular.

The architecture of Angular comprises Modules, Components, Templates, Metadata, Directives, and Services:

NgModules

Angular framework has various libraries that are grouped as modules in order to build an application. Angular applications are modular in nature and are constructed by assembling various modules. Modules may have components, services, functions, and/or values. Some modules may have a collection of other modules and are known as library modules.

Angular packages, such as core, common, http, and router that are prefixed with @angular comprise many modules. We import what our application needs from these library modules as follows:

import {Http, Response} from @angular/http'; 

Here, we import Http and Response from the library module, @angular/http. @angular/http refers to a folder in the Angular package. Any module defined to be exported can be imported into another module by referring to the filename of the module.

Note: this import statement was introduced in ES2015 and is used to import objects or function that are exported from other modules or scripts


However, we can also refer to the folder as we referred to @angular/http. This can be achieved by adding an index.ts file to the folder and adding the code to export modules from the folder. This is a best practice suggested by Angular's style guide and is called the barrel technique:

export * from './http'; 

This is the export statement in the index.ts found in @angular/http. The statement means that it exports all the modules in HTTP and that they can be imported to our application wherever needed.

When we write an Angular application, we start by defining an AppComponent (not necessarily with the same name) and exporting it.

Components

A component is a class that has properties and methods to be used in the view. These properties and methods exposed to view enable the view to interact with components. We code logic that supports the view in the component class:

For example, next is a component class book that has a properties title and author and a getPubName method that returns the name of the book:

export class BookComponent { 
  title: string; 
  author: string; 
  constructor() { 
      this.title = 'Learning Angular for .Net Developers'; 
      this.author = 'Rajesh Gunasundaram'; 
  } 
  getPubName() : string { 
    return 'Packt Publishing'; 
  } 
} 
Note: We will be using TypeScript in all our examples in this book.

The life cycle of a component is managed by Angular according to user interactions with the application. We can also add an event method that will be fired according to the state changes of the component. These event methods are known as life cycle hooks and are optional.

We will learn in detail about components in Chapter 5, Implementing Angular Routing and Navigation.

Templates

Templates can be thought of as a representation of a component that is visualized according to the UI/UX needs of an application. A component will have a template associated with it. The template is responsible for displaying and updating data according to user events:

Here is a simple template that displays the title and author of a book:

<h1>Book Details</h1> 
<p>Title of the Book: {{title}}</p> 
<p>Author Name : {{author}}</p> 

Here, the title and author values wrapped in curly braces will be supplied by the associated component instance.

We will discuss templates and their syntax in detail in Chapter 8, Template and Data Binding Syntax.

Metadata

A class can be turned into a component by annotating it with @Component and passing the necessary metadata, such as selector, template, or templateUrl. Angular considers a class as a component only after attaching metadata to it:

Let's revisit the BookComponent class we defined earlier. Angular does not consider this class as a component unless we annotate it. TypeScript leverages the ES7 feature by providing a way to decorate a class with metadata as follows:

@Component({ 
  selector:    'book-detail', 
  templateUrl: 'app/book.component.html' 
}) 
export class BookComponent { ... } 

Here, we have decorated the BookComponent class with @Component and attached metadata selector and templateUrl. It means that, wherever Angular sees the special <book-detail/> tag in the view, it will create an instance of BookComponent and render the view assigned to templateUrl, which is book.component.html.

A decorator provided by TypeScript is a function that takes configuration parameters that are used by Angular to create an instance of the component and render the associated view. Configuration parameters may also have information about directives and providers, which will be made available by Angular when the component is created.

Data Binding

Data Binding is one of the core responsibilities of developers when writing code to bind data to the user interface and update changing data according to user interactions with the user interface. Angular has reduced the burden of writing large amounts of code to handle Data Binding:

Angular handles Data Binding by coordinating with templates and components. The templates provide instructions to Angular on how and what to bind. There are two types of binding in Angular: globally One-way Data Binding and Two-way Data Binding. One-way Data Binding deals with either binding data from the component to the DOM or from the DOM to the component. Two-way Data Binding deals with both sides of communication, that is, the component to the DOM and the DOM to the component.

<div>Title: {{book.title}}<br/> 
  Enter Author Name: <input [(ngModel)]="book.author"> 
</div> 

Here, book.title wrapped in double curly braces deals with One-way Data Binding. The value of book title, if available in the component instance, will be displayed in the view. book.author, assigned to the ngModel property of the input element, deals with Two-way Data Binding. If the component instance has a value in the author property, then it will be assigned to the input elements, and if the value is changed by the user in the input control, then the updated value will be available in the component instance.

We will learn in detail about Data Binding in Chapter 8, Template and Data Binding Syntax.

Directives

A directive is instructions or guidelines for rendering a template. A class decorated with @Directive to attached metadata is called a directive. There are three types of directive supported by Angular, namely Component Directive, Structural Directive, and Attribute Directive:

A component is one form of a directive with a template that is decorated with @Component: it is actually an extended @Directive with a template feature:

<book-detail></book-detail> 

Structural Directives manipulate the DOM elements and alter their structure by adding, removing, and replacing DOM elements. The following code snippet uses two Structural Directives:

<ul> 
<li *ngFor="let book of books"> 
    {{book.title}} 
</li> 
</ul> 

Here, the div element has a *ngFor directive that iterates through the books collection object and replaces the title of each book.

An Attribute Directive helps to update the behavior or the appearance of an element. Let's use the Attribute Directive to set the font size of a paragraph. The following code snippet shows an HTML statement implemented with an Attribute Directive:

<p [myFontsize]>Fontsize is sixteen</p> 

We need to implement a class annotated with @Directive along with the selector for the directive. This class should be implemented with the instructions on the behavior of the directive:

import { Directive, ElementRef, Input } from '@angular/core'; 
@Directive({ selector: '[myFontsize]' }) 
export class FontsizeDirective { 
    constructor(el: ElementRef) { 
       el.nativeElement.style.fontSize = 16; 
    } 
} 

Here, Angular will look for elements with the [myFontsize] directive and sets the font size to 16.

It is necessary to pass the myFontSize directive to the declarations metadata of @NgModule as follows:

import { NgModule } from '@angular/core'; 
import { BrowserModule } from '@angular/platform-browser'; 
import { AppComponent } from './app.component'; 
import { FontsizeDirective } from './fontsize.directive'; 
@NgModule({ 
  imports: [ BrowserModule ], 
  declarations: [ 
    AppComponent, 
    FontsizeDirective 
  ], 
  bootstrap: [ AppComponent ] 
}) 
export class AppModule { } 

We will discuss directives in detail in Chapter 6, Creating Directives and Implementing Change Detection.

Services

Services are user-defined classes used to solve problems. Angular recommends only having template-specific codes in components. A component's responsibility is to enrich the UI/UX in the Angular application and delegate business logic to services. Components are consumers of services:

Application-specific or business logic such as persisting application data, logging errors, and file storage should be delegated to services, and components should consume the respective services to deal with the appropriate business or application-specific logic:

For example, we can have a service called BookService that deals with inserting new books, editing or deleting existing books, and fetching a list of all the books available.

We will see more about services in Chapter 11, Implementing Angular Pipes.

Dependency Injection

When an instance of a class is created, supplying the required dependencies of that class for it to function properly is called Dependency Injection. Angular provides a modern and improved version of Dependency Injection:

In Angular, the injector maintains the containers to hold the instances of the dependencies and serves them as and when required. If the instance of a dependency is not available in the container, then the injector creates an instance of the dependency and serves it:

As stated earlier, components have logic that is related to templates and mostly consume services to perform business logic. So, components depend on services. When we write code for components, we create a parameter constructor that takes the service as an argument. It means that creating an instance of the component depends on the service parameter in the constructor. Angular requests that the injector provide the instance of the service in the parameter of the constructor of the component. The injector will serve the instance of the requested service, if available; otherwise, it creates a new one and serves it:

export class BookComponent { 
  constructor(private service: BookService) { } 
} 

In this code snippet, the : symbol comes from TypeScript and is not Angular syntactical sugar. The private keyword is also from TypeScript and enables assigning the passed constructor to the class instance automatically. The type information is used to infer the type to be injected. The BookComponent has a dependency to BookService and is injected in the constructor. So when an instance of the BookComponent is created, Angular will also make sure the instance of BookService is readily available for the BookComponent instance to consume.

The injector has knowledge of the dependencies to be created from providers that are configured with the required dependency types when bootstrapping the application or when decorating the components, as follows:

@NgModule({ 
  imports: [BrowserModule], 
  declarations: [AppComponent,], 
  providers: [BookService], 
  bootstrap: [ AppComponent ] 
}) 
export class AppModule { } 

The preceding code snippet adds BookService as a provider to the bootstrap function. The injector will create an instance of BookService and keep it available in the container for the entire application to inject whenever it's requested:

@Component({ 
  providers:   [BookService] 
}) 
export class BookComponent { ... } 

The preceding code snippet adds BookService as a provider in the metadata of the component. The injector will create an instance of BookService when it encounters a request to create an instance of BookComponent.

We will discuss Dependency Injection and hierarchical Dependency Injection in detail in
Chapter 12
, Implementing Angular Services.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime