Introduction:
Angular is a platform and framework for building client applications in HTML and TypeScript. Angular is written in TypeScript. It implements core and optional functionality as a set of TypeScript libraries that you import into your apps. Angular
is not a higher version AngularJs but it is completely
rewritten. It has lot of improvements when compared with AngularJs like
"Performance, Mobile support, Component based development, More language
choice".
Why Angular:
- Angular is 5 times faster than AngularJs. Angular has faster initial loads, change detection and improved rendering times.
- Mobile Support: With angular we can build a single application that can run on mobile and desktop devices.
- Component Based Development:In Angular everything is component. Components are the building block of Angular application.
- More language choices:
- ECMAScript 5
- ECMAScript 6 (also called ES 2015)
- TypeScript
- PureScript etc
What is Type Script:
TypeScript is a free and open-source programming language developed by Microsoft. It is a superset of JavaScript and compiles to JavaScript through a process called transpilation. Using TypeScript to build angular applications provides several benefits.
- Intellisense
- Autocompletion
- Code navigation
- Advanced refactoring
- Strong Typing
- Supports ES 2015 (also called ES 6) features like classes, interfaces and inheritance.
Because of all these benefits writing, maintaining and refactoring applications can be an enjoyable experience. So obviously TypeScript has become the number one choice of many developers for developing Angular applications. Besides Visual Studio, TypeScript is supported by several other editors like
- Visual Studio Code
- Eclipse
- WebStorm
- Atom
- Sublime Text etc.
Main Building Blocks of an Angular application:
- Modules
- Components
- Templates, directives, Pipe and data binding
- Services and dependency injection
What Is A Modules:
In simple terms an Angular Module is a class decorated with @NgModule decorator. An Angular Module is a mechanism to group components, directives, pipes and services that are related to a feature area of an angular application.
For example, if you are building an application to manage employees, you might have the following features in your application.
Application Feature |
Description |
Employee Feature |
Deals with creating, reading, updating and deleting employees |
Login Feature |
Deals with login, logout, authenticate and authorize users |
Report Feature |
Deals with generating employee reports like total number of employees by department, top 10 best employees etc |
To group the components, directives, pipes and services related to a specific feature area, we create a module for each feature area. These modules are called feature modules.
Every Angular app has at least one NgModule class, the root module, which is conventionally named AppModule and resides in a file named app.module.ts. You launch your app by bootstrapping the root NgModule.
In addition to feature modules, an Angular application also contains the following modules.
- Root Module: Every Angular application has at least one module, the root module. By default, this root application module is called AppModule. We bootstrap this root module to launch the application.
- Core Module: The most important use of this module is to include the providers of http services. Services in Angular are usually singletons. So to ensure that, only one instance of a given service is created across the entire application, we include all our singleton service providers in the core module. In most cases, a CoreModule is a pure services module with no declarations. The core module is then imported into the root module (AppModule) only. CoreModule should never be imported in any other module.
- Shared Module: This module contains reusable components, directives, and pipes that we want to use across our application. The Shared module is then imported into specific Feature Modules as needed.
- Routing Module: An angular application may also have one or more routing modules for application level routes and feature module routes.
Advantage of Angular Module:
- Organizing Angular Application
- Code Reuse
- Code Maintenance
- Performance
NgModule metadata/@NgModule Decorator:
The @NgModule() decorator is a function that takes a single metadata object, whose properties describe the module. The most important properties are as follows.
- declarations: The components, directives, and pipes that belong to this NgModule.
- exports: The subset of declarations that should be visible and usable in the component templates of other NgModules.
- imports: Other modules whose exported classes are needed by component templates declared in this NgModule.
- providers: Creators of services that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level, which is often preferred.)
- bootstrap: The main application view, called the root component, which hosts all other app views. Only the root NgModule should set the bootstrap property.
What
Is A Component:
Component defines a class that
contains application data and logic and is associated with an HTML template
that defines a view to be displayed in a target environment.
A component in
Angular is a class with a template and a decorator. So, in simple terms a
component in Angular is composed of these 3 things
·
Template - Defines the user interface. Contains
the HTML, directives and bindings.
·
Class - Contains the code required for
template. Just like a class in any object-oriented programming language like C#
or Java, a class in angular c an contain methods and properties. Properties
contain the data that we want to display in the view template and methods
contain the logic for the view. We use TypeScript to create the class.
·
Decorator - Decorators are functions that
modify JavaScript classes. We use the Component decorator provided by Angular
to add metadata to the class. A class becomes an Angular component, when it is
decorated with the Component decorator.
Example:
Template:
It
defines the user interface that contains the HTML, directives and bindings. We
can define template in two different way.
1. With an Inline template: For inline
template we need to use template
property for writing html in single/multi line. Angular recommends using templateUrl property when you have html
of more than three line.
Use special Char pair “ `
` ” for multiline like below
`<h1>
Hello
</h1>`
a. We lose visual
studio editor intellisense, code completion and formatting features
b. TypeScript code
is not easier to read and understand when it is mixed with inline html
template.
2.
With an external
view template: We write html view in external html file with
.html and use templateUrl property
to set the location of html file. Location is relative to index.html
a. We have visual
studio editor intellisense, code completion and formatting features
b. Code is clean and
easier to read and understand
Styling Angular Components:
·
Styles in external stylesheet - Styles.css
·
Styles inline in the component html file
·
Styles in the component html file using <style> tag
·
Specify the styles in the component TypeScript file
using the @component decorator Styles property
·
Specify the styles in the component TypeScript file
using the @component decorator StyleUrls property
·
What is A Directives:
A directive is a custom HTML element that is used to extend
the power of HTML. A directive is a class with a @Directive() decorator.
There are three kinds of directives in an Angular 2
application.
1. Components: Angular Component also refers to a
directive with a template which deals with View of the Application and also
contains the business logic. It is very useful to divide your Application into
smaller parts. In other words, we can say that Components are directives that
are always associated with the template directly.
2. Structural directives: Structural
directives are able to change the behavior of DOM by adding and removing DOM
elements. The directive NgFor, NgSwitch, and NgIf is the best example of
structural directives.
3. Attribute directives: Attribute
directives are able to change the behavior of DOM. The directive NgStyle is an
example of Attribute directives which are used to change styles elements at the
same time.
Example Attribute directive:
Note: Angular does not
allow to use more than one structural directive in single element that’s why we
need container component.
What is A Pipe:
Angular
pipes let you declare display-value transformations in your template HTML. A
class with the @Pipe decorator defines a function that transforms input values
to output values for display in a view.
Transform
data before display. Built in pipes include lowercase, uppercase, decimal,
date, percent, currency etc
To
apply a pipe on a bound property, use the pipe character " | "
We
can also chain pipes
Pass
parameters to pipe using colon ": "
Pure and Impure Pipe:
There
are two categories of pipes: pure and impure.
Pipes are pure by default. You make a pipe impure by setting its pure flag to false.
Pure pipes:
Angular
executes a pure pipe only when it detects a pure change to the input value. A
pure change is either a change to a primitive input value (String, Number,
Boolean, Symbol) or a changed object reference (Date, Array, Function, Object).
Angular
ignores changes within (composite) objects. It won't call a pure pipe if you
change an input month, add to an input array, or update an input object
property.
Impure pipes:
Angular
executes an impure pipe during every component change detection cycle. An
impure pipe is called often, as often as every keystroke or mouse-move.
With that concern
in mind, implement an impure pipe with great care. An expensive, long-running
pipe could destroy the user experience.
Angular custom pipe:
Step 1: Create a
custom pipe called employeeTitlePipe as employeeTitle.pipe.ts file.
Step 2: Register "EmployeeTitlePipe" in the
angular module.
Step 3: In "employeeList.component.html" use
the "EmployeeTitlePipe" as
shown below.
What is Data binding:
Data binding is a core concept in
Angular and allows to define communication between a component and the DOM,
making it very easy to define interactive applications without worrying about
pushing and pulling data.
There are four forms of data binding
and they differ in the way the data is flowing.
From the Component to the DOM
·
Interpolation: {{
value }} : This adds the value of a property from the
component:
<li>Name:
{{ user.name }}</li> <li>Email: {{ user.email }}</li>
·
Property binding:
[property]="value": With property binding, the value is
passed from the component to the specified property, which can often be a
simple html attribute:
<input
type="email" [value]="user.email">
Here are two more
examples, one that applies a background-color from the value of selectedColor in the component and one
that applies a class name if isSelected
evaluates to true:
<div
[style.background-color]="selectedColor">
<div
[class.selected]="isSelected">
We can also use the
alternate syntax with bind- prefix. This is known as canonical form
<button bind-disabled='isDisabled'>Click
me</button>
From the DOM to the Component
·
Event binding:
(event)="function": When a specific DOM event happens (eg.:
click, change, keyup), call the specified specified method in the component. In
the example below, the cookBacon() method from the component is called when the
button is clicked:
<button
(click)="cookBacon()"></button>
we can also use the on- prefix alternative as shown below.
This is known as the canonical form
<button on-click="onClick()">Click
me</button>
Two-Way
·
Two-way data
binding: [(ngModel)]="value": Using what’s called the banana in a
box syntax, two-way data binding allows to have the data flow both ways. In
this example, the user.email data property is used as the value for the input,
but if the user changes the value, the component property gets updated
automatically to the new value:
<input
type="email" [(ngModel)]="user.email">
What is the difference between HTML element
attribute and DOM property
- Attributes
are defined by HTML, whereas properties are defined by the DOM.
- Attributes
initialize DOM properties. Once the initialization complete, the
attributes job is done.
- Property
values can change, whereas attribute values can't.
What is a
container and nested component:
In the example below, we have 2
components, One of the component displays the list of employees. We have
already built this component in our previous videos in this series. We named
this component EmployeeListComponent.
The other component displays the radio
buttons and the count of employees. We have not created this component yet. We
will create it in this video. We will call this component EmployeeCountComponent.
We will nest EmployeeCountComponent in
EmployeeListComponent. So EmployeeCountComponent becomes the nested component
or child component and EmployeeListComponent becomes the container component or
parent component.
Understanding
@Input, @Output and EventEmitter:
A tool to exchange data
First of all, the idea of Input and
Output is to exchange data between components. They are a mechanism to
send/receive data from one component to another. Input is used to receive data
in whereas Output is used to send data out. Output sends data out by exposing
event producers, usually EventEmitter objects. So, when you see code like this
that
means hey, I am expecting data being sent to me. I will receive it and store it
into my item property by the way, I will produce and send data out via the onChange property.
@Input in action:
Decorating a property
with @Input() decorator makes the property an input property.
Passing data from the parent component
(EmployeeListComponent) to the child component (EmployeeCountComponet):
Note: In the filter method we are using
tripple equals (===) instead of double equals (==). The table below explains
single, double and tripple equals in TypeScript.
Operator
|
Use to
|
=
|
Assign a value
|
==
|
Compare two
values
|
===
|
Compare two
values and their types
|
@Output and EventEmitter:
Decorating a property
with @Output() decorator makes the property an output property.
Child Component (EmployeeCountComponent)
Parent Component (EmployeeListComponent)
An Interface in TypeScript:
An
interface is an abstract type. It only contains declarations of properties,
methods and events. The implementation for the interface members is provided by
a class that implements the interface. If a class that implements the interface
fails to provide implementation for all the interface members, the language
compiler raises an error alerting the developer that something has been missed.
1. Use interface
keyword to create an interface
2. It is common to
prefix the interface name with capital letter "I". However, some
interfaces in Angular does not have the prefix "I". For example,
OnInit interface
3. Interface members
are public by default and does not require explicit access modifiers. It is a
compile time error to include an explicit access modifier. You will see an
error message like - public modifier cannot appear on a type member.
4. A class that
implements an interface must provide implementation for all the interface
members unless the members are marked as optional using the ? operator
5. Use the
implements keyword to make a class implement an interface
6. TypeScript
interfaces exist for developer convenience and are not used by Angular at
runtime. During transpilation, no JavaScript code is generated for an
interface. It is only used by Typescript for type checking during development.
7. To reduce the
amount of code you have to write, consider using short-hand syntax to
initialise class properties with constructor parameters
Angular Component lifecycle hooks:
In
Angular, every component has a life-cycle, a number of different stages it goes
through from initializing to destroying. There are 8 different stages in the
component lifecycle. Every stage is called life cycle hook events.
Constructor:
The
constructor of the component class is called before any other component
lifecycle hook. If our component is based on any dependencies, the constructor
is the best place to inject those dependencies.
ngOnChanges:
The ngOnChanges will
be called first when the value of a bound property changes. It executes, every
time the value of an input property changes. It will receive a changes map,
containing the current and previous values of the binding, wrapped in a SimpleChange.
{"brand":{"previousValue":"","currentValue":"BMW"}}
In
the case above, one change to the input property brand is
reported. The value of this property has been changed from an empty string to
the string “BMW”.
ngOnInit:
The ngOnInit method of a component is
called directly after the constructor and after the ngOnChange is triggered for the
first time. It is the perfect place for initialization work.
Invoked when
given component has been initialized. This hook is only called once after
the first ngOnChanges
Use ngOnInit() for
two main reasons:
1. To perform
complex initializations shortly after construction.
2. To set up the
component after Angular sets the input properties.
An ngOnInit()
is a good place for a component to fetch its initial data.
Note: Remember
also that a directive's data-bound input properties are not set until after
construction. That's a problem if you need to initialize the directive based on
those properties. They'll have been set when ngOnInit() runs.
ngDoCheck:
Invoked
when the change detector of the given component is invoked. It allows
us to implement our own change detection algorithm for the given
component.
ngDoCheck and ngOnChanges should not be
implemented together on the same component.
Use
the DoCheck hook to detect and act upon changes that Angular doesn't catch on
its own.
If
you have a object with some property and internal property getting in that case
ngOnChange() event will not fire to over come these issue we need custom change
detection, it this scenario this is required.
ngAfterContentInit:
The
ngAfterContentInit lifecycle hook is called after ngOnInit when
the component or directive’s content has been initialised; basically when all
the bindings of the component have been checked for the first time.
ngAfterContentChecked:
Called after
every check of the component or directive’s content, effectively when
all the bindings of the components have been checked; even if they haven’t
changed.
ngAfterViewInit:
Called after ngAfterContentInit when
the component’s view has been initialised. Applies to components only.
ngAfterViewChecked:
Called after
every check of the component’s view. Applies to components only. When
all the bindings of the children directives have been checked; even if they haven’t
changed. It can be useful if the component is waiting for something coming from
its child components.
ngOnDestroy:
This
method will be invoked just before Angular destroys the component.
Use this hook to unsubscribe observables and detach event handlers
to avoid memory leaks.
Put cleanup
logic in ngOnDestroy(), the logic
that must run before Angular destroys the directive.
Angular Services:
A service in Angular is generally used
when you need to reuse data or logic across multiple components. Using a
service ensures we are not violating one of the Software principles - DRY
((Don't repeat yourself). The logic or data access is implemented once in a
service, and the service can be used across all the components in our
application. @Injectable() decorator is used to create a service.
Without the
service you would have to repeat your code in each component. Imagine the
overhead in terms of time and effort required to develop, debug, test and
maintain the duplicated code across multiple places instead of having that
duplicated code at one central place like a service and reusing that service
where required.
Providing services:
1.
Root (Singleton): root/userModule
2. Module:
3. Component:
Dependency Injection:
It's a coding
pattern in which a class receives its dependencies from an external source
rather than creating them itself. A dependency in Angular can be a
class, referred as a service or even a simple object. Angular’s Dependency
Injection is based on providers, injectors, and tokens.
Every Angular
module has an injector associated with it. The injector is responsible to
create the dependencies and inject them when needed. Dependencies are added to
the injector using the providers property of the module metadata.
Every
dependency is a key-value pair, where the key is a token and the value is the
object of the dependency. For Services, Angular creates the tokens by itself.
For objects, we need to create the tokens.
When
a dependency is injected into another block (viz., a component, directive or
service), the injector resolves the object from its list of dependencies using
the token.
The DI in Angular basically
consists of three things:
·
Injector - The
injector object that exposes APIs to us to create instances of dependencies.
·
Provider - A provider
is like a recipe that tells the injector how to create an instance of a
dependency. A provider takes a token and maps that to a factory function that
creates an object.
·
Dependency - A
dependency is the type of which an object should be created.
Angular Injector:
The
injector object that exposes APIs to us to create instances of dependencies. In
Angular we have one injector at the application root level and hierarchical
injectors that parallel an application's component tree. This means in Angular
2, we have one root injector plus an injector at every component level
If a service
is registered with the root injector, then that service is available for all
components in our entire application including the components in lazy loaded
modules. We will discuss lazy loaded modules in a later video in this series.
If a service
is registered with the injector at the Application Root component level, then
that service is available for all the components in the application except the
components in lazy loaded modules.
If
a service is registered with a specific component injector, then that service
is available for that component and any of it's children. For example, if we
register a service with Component X injector, then that service is available
for Components X, Y & Z but not for Component A. Similarly, if a we
register a service with Component A injector, then that service is available
only for Component A but not for Components X, Y & Z
Great job for publishing such a nice article. Your article isn’t only useful but it is additionally really informative. Thank you because you have been willing to share information with us. Fortinet managed services
ReplyDelete