Angular follows a two-way data flow pattern, meaning you can send data up and down the component tree.
Everything in the Angular is a component.
Interpolation is the way to inject some value into HTML. We are injecting title from the component class to the HTML.
<h1>
Welcome to {{ title }}!
</h1>
Property Binding is used to send the information from the component class to view with the square brackets []
.
<app-header [title]="title"></app-header>
Event Binding is used to send the information from the view class to component class with the normal brackets ()
.
<app-header (click)="updateHeader()"></app-header>
We have @Input()
headerTitle
in the header and we use property binding [headerTitle]
in the app component to pass the title.
<app-header [headerTitle]="title"></app-header>
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
constructor() { }
@Input() headerTitle: string;
ngOnInit() {
}
}
We have @Output
decorator and EventEmitter
to send the information from the child component to the parent component.
// header.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
constructor() { }
@Input() headerTitle: string;
@Output() navOut = new EventEmitter();
onNavLink(linkName: string) {
this.navOut.emit(linkName);
}
ngOnInit() {
}
}
When the event is emitted, it will be captured here in the app component as shown below. We define onNavigation() method in the app component to capture the emitted value and assign that to linkName property. We can place this linkName property in the HTML file with an interpolation {{linkName}}.
// app.component.html
<app-header
[headerTitle]="title"
(navOut)="onNavigation($event)"
>
</app-header>
//app.component.ts
export class AppComponent {
title = 'angular-communication';
linkName: string;
onNavigation(navLink: string) {
this.linkName = navLink;
}
}
Define Subject in the services which receives the data from the Header component. Footer component subscribes to the Subject defined in the services and receives data as soon as data is emitted by Subject with the next
function.
// app.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AppService {
constructor() { }
public isUserLoggedIn = new Subject();
setUserLoggedIn(loggedIn: boolean) {
this.isUserLoggedIn.next(loggedIn);
}
}
// footer.component.ts
export class FooterComponent implements OnInit {
constructor(private appService: AppService) { }
isUserLoggedIn: boolean;
ngOnInit() {
this.appService.isUserLoggedIn.subscribe((userLoggedIn: boolean) => {
this.isUserLoggedIn = userLoggedIn;
});
}
}
// header.component.ts
export class HeaderComponent implements OnInit {
constructor(private appService: AppService) { }
loginLabel = 'login';
onNavLink(linkName: string) {
if (linkName === 'logout') {
this.loginLabel = 'login';
this.appService.setUserLoggedIn(false);
} else if (linkName === 'login') {
this.loginLabel = 'logout';
this.appService.setUserLoggedIn(true);
}
this.navOut.emit(linkName);
}
}
<!-- app.component.html -->
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<app-header
[headerTitle]="title"
(navOut)="onNavigation($event)"
(setLoggedInFlag)="setLoggedInUser($event)"
>
</app-header>
<app-footer
[isUserLoggedIn]="loginFlag"
>
</app-footer>
</div>
// app.component.ts
// removed for brevity
export class AppComponent {
title = 'angular-communication';
linkName: string;
loginFlag: boolean;
setLoggedInUser(loggedIn: boolean) {
this.loginFlag = loggedIn;
}
}
// footer.component.ts
// removed for brevity
export class FooterComponent implements OnInit {
constructor() { }
_isUserLoggedIn: boolean;
get isUserLoggedIn(): boolean {
return this._isUserLoggedIn;
}
@Input()
set isUserLoggedIn(value: boolean) {
this._isUserLoggedIn = value;
}
}
@ViewChild is one of the common decorators we use in Angular. With this we can obtain the reference of the custom angular component by querying the template.
// app.ts
// parent html
<div class="parent">
<h2>I am a Parent</h2>
<app-child #child></app-child>
</div>
// parent component class. removed everything for brevity
export class ParentComponent implements OnInit, AfterViewInit {
constructor() { }
@ViewChild('child') childComp: ChildComponent;
ngAfterViewInit() {
this.childComp.title = 'title coming from parent';
}
}
// child.ts
// child html
<div>
<h4>{{title}}</h4>
</div>
// child component class
export class ChildComponent implements OnInit {
constructor() { }
title = 'I am a child';
ngOnInit() {
}
}
<app-welcome-message>
<h2>Welcome to APP!</h2>
</app-welcome-message>
<!-- app-weelcome-message -->
<div>
<ng-content></ng-content>
</div>
NGRX is a state management tool inspired by redux for the Angular Applications.