Overview
Components are the main building block for Angular app.
An HTML template.
A Typescript class that defines behavior.
A CSS selector that defines the style of component.
Generating components from Angular CLI is
ng generate component <component-name>
What is Component Decorator?
@Component({
selector: 'app-component',
templateUrl: './app-component.component.html',
styleUrls: ['./app-component.component.css']
})
selector:
Every component requires a CSS selector.
Selector instructs Angular to instantiate this component wherever it finds the corresponding tag in HTML file.
templateUrl:
Define a template for your component in one of two ways
By referencing an external file (Better-way).
Define directly within that component
styleUrls:
- You can define or give a file for css of this particular component.
Component Lifecycle
How can a component decide the behavior of elements in multiple scenarios?
This life cycle hook gives us to chance to change the behavior of components and act on components at an appropriate moment.
There are many life cycle hooks are available which execute in the below sequence.
ngOnChanges()
This is called when any input properties are changed.
This method receives a SampleChanges object from previous and current properties values
ngOnInit()
Initialize the component after angular displays the properties and set the values for the same.
Called after ngOnChanges() and called first ngOnInit() when ngOnChanges() is not there.
ngDoCheck()
Detect the changes that angular won't detect(because angular detects changes on only object reference)
Called immediately after ngOnChanges on every change detection run or immediately after ngOnInit first run.
This lifecycle detects change also when an object mutates.
ngAfterContentInit()
Content is what is passed as children usually to be projected at some
<ng-content>
element of a component.This is called after components external content has been initialized.
Called only one time after ngDoCheck() is called.
ngAfterContentChecked()
This is called after the component view and its child views has been initialized.
Called immediately after every subsequent of ngDoCheck() is called.
ngAfterViewInit()
View is the template of the current component.
This is called after initializing the component's view and it's child view.
(This is called for only during first change detection cycle.)
Called only one time after ngContentChecked().
ngAfterViewChecked()
This is called after ngAfetrViewInit() and every subsequent of ngAfterViewChecked().
(Called for every running change detection cycle on component and it's child)
ngOnDestroy()
Clean up the process and destroys the component.
Unsubscribe observables to avoid memory leaks.
Called immediately before angular destroys the application.
Component Interaction
In angular mainly four types of interaction from component to component.
Parent to Child communication (
@Input
).Child to Parent communication (
@Output
).Transfer data between sibling components.
Transfer data using
@ViewChild
operator.
Parent to Child Communication
We are using
@Input
decorator in Child component to take value from Parent component which is set by Parent itself.// This is child.component.ts file import { Component, Input } from '@angular/core'; @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'] }) export class ChildComponent { @Input() ParentToChild?:string; // we have to use this variable in .html file of this component. }
<!-- This is child.component.html file--> <p>This is child component</p> <strong>{{ParentToChild}}</strong>
Now pass data from Parent component using input.
(Whatever data we pass in input that reflects on child component)// This is parent.component.ts file import { Component, DoCheck, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { FormControl } from '@angular/forms'; @Component({ selector: 'app-parent', templateUrl: './parent.component.html', styleUrls: ['./parent.component.css'] }) export class ParentComponent implements OnInit { p2cControl:FormControl<string>=new FormControl(); fromParent?:string=''; ngOnInit(){ this.p2cControl.valueChanges.pipe().subscribe(q=>{ this.fromParent=q; }) } }
<!-- This is parent.component.html file--> <p>This is parent component</p> <label for="fname">Whatever you type in below is transfer to child</label> <ul></ul> <input type="text" id="p2cid" [formControl]="p2cControl" name="p2Ccid"> <app-child [ParentToChild]=fromParent></app-child>
Child to Parent Communication
We are using
@Output
decorator for Child to Parent data transfer andparent listens for child's event.
The parent binds to that event property and reacts to those events.
//This is chl.component.ts file
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit{
@Output() ChildToParent=new EventEmitter<string>();
c2pControl:FormControl<string>=new FormControl();
ngOnInit(){
this.c2pControl.valueChanges.pipe().subscribe(q=>{
this.ChildToParent.emit(q);
})
}
}
<!--This is child.component.html file-->
<input type="text" #c2pid [formControl]="c2pControl" name="c2Pname">
Now get data from parent component and event emit through parent.component.html
<!-- This is parent.component.html file--> <strong>{{fromChild}}</strong> <app-child [ParentToChild]=fromParent (ChildToParent)="addOutput($event)"></app-child>
// This is parent.component.ts file import { Component, DoCheck, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { FormControl } from '@angular/forms'; @Component({ selector: 'app-parent', templateUrl: './parent.component.html', styleUrls: ['./parent.component.css'] }) export class ParentComponent implements OnInit { p2cControl:FormControl<string>=new FormControl(); fromChild?:string=''; } addOutput(value:string) { this.fromChild=value; } }
Data sharing using @ViewChild
operator.
@Viewchlid
using Component.In this way parent component will be able to access the properties and methods of child component.
The child component selector will be used in parent component HTML template.
// This is child.component.ts file import { Component } from '@angular/core'; @Component({ selector: 'app-child', template: '<b>{{message}}</b>' }) export class ChildComponent { messageShow() { this.message = "Message: " +"Yayyy this viewchild component works" ; } }
// This is parent.component.ts file import { Component, ViewChild } from '@angular/core'; import { ChildComponent } from './number.component'; @Component({ selector: 'app-parent', templateUrl: './parent.component.html', styleUrls: ['./parent.component.css'] }) export class ParentComponent { @ViewChild(ChildComponent) private childComponent = {} as ChildComponent; show() { this.childComponent.messageShow(); } }
<!-- This is parent.component.html file--> <;h3>@ViewChild using Component</h3>; Example: <button type="button" (click)="show()">Click me</button> <br/><br/> <app-child></app-child>
@ViewChild
using Directive.This can instantiate a directive within a component and in this way the component will be able to access the directive methods.
//This is directive.directive.ts file import { Directive, ElementRef, AfterViewInit } from '@angular/core'; @Directive({ selector: '[directive]' }) export class Directive implements AfterViewInit{ constructor(private elRef: ElementRef) { } change() { this.elRef.nativeElement.innerText= 'ChangedText'; } }
//This is parent.component.ts file import { Component, ViewChild } from '@angular/core'; import { CpColorDirective } from './cpcolor.directive'; @Component({ selector: 'app-parent', templateUrl: './parent.component.html', styleUrls: ['./parent.component.css'] }) export class ParentComponent { @ViewChild(directive) private refDirective = {} as Directive; change() { this.refDirective.change(); } }
<!-- This is parent.component.html file--> <;h3>@ViewChild using Directive</h3>; Example: <p directive>This text will change after button click</p> <div> <button type="button" (click)="change()">Click me</button> </div>
use
@ViewChid
to inject a reference to a DOM element.In some cases we may require to change or modified the current component data or need to some operation with component's element then we have to use this method.
Like we discuss the example below
viewchildcomponent
.But, before we move forward to eg. we know the...
When variables are injected via
@ViewChild
?The value of this injected member variable is not immediately available at component construction time!
Angular will fill in this property automatically, but only later in the component lifecycle, after the view initialization (
nfAfterViewInit()
) is completed.// This is viewchildcomponent.ts file import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core'; @Component({ selector: 'app-viewchildcomponent', templateUrl: './viewchildcomponent.component.html', styleUrls: ['./viewchildcomponent.component.css'] }) export class ViewchildcomponentComponent implements AfterViewInit { @ViewChild('viewchildcomponent') viewchildcomponent?:ElementRef; ngAfterViewInit(){ console.log(this.viewchildcomponent?.nativeElement); } }
<!-- This is viewchildcomponent.html file--> <p #viewchildcomponent> viewchildcomponent works!</p>
use
@ViewChid
to inject a reference to a DOM element of a component.You can same achieve for this reference to a DOM element of a component.
You can take
component as a reference
in your parent-component and modify the content or using for other process also.Like for below example
parent-component
andviewchildcomponent
.// This is parent.component.ts file import { AfterViewInit, Component,ViewChild } from '@angular/core'; import { ViewchildcomponentComponent } from '../viewchildcomponent/viewchildcomponent.component'; @Component({ selector: 'app-parent', templateUrl: './parent.component.html', styleUrls: ['./parent.component.css'] }) export class ParentComponent implements AfterViewInit{ @ViewChild('viewchild') component?: ViewchildcomponentComponent; ngAfterViewInit() { console.log('Values on ngAfterViewInit():'); console.log("component:", this.component); } }
<!--This is parent.component.html file--> <p>This is parent component</p> <app-viewchildcomponent #viewchild></app-viewchildcomponent>
yupp๐๐ that's it btw you can check out more for viewchild in angular-university and other.
Thankyou ๐ค๐ค