Components & Databinding Deep Dive
Usually we splitting Apps
into Components
. so how does component communicate
with each other?
Property Binding
Generally all properties or components are only accessible inside these components not from outside. But you can expose property to the world by adding @Input
decorator, so that any parent component is now able to pass data to our exposed properties downstream
.
Binding to custom properties
- Syntax
1 | // component |
- Alias
1 | // component |
Event Binding
The other direction(upstream) what if we have a component and something changes in there and we want inform the parent component.
Binding to custom events
- Syntax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// child component
@Output() someEvent: new EventEmitter<dataType>();
onOtherEvent(){
this.someEvent.emit(data)
}
// child template
<element (otherEvent)="onOtherEvent()">
//==================================================
// host template
<selector (someEvent)="someEvented($event)"></selector>
// parent component
someEvented(data: dataType){
}Alias
1
2
3
4@Output('alias') someEvent: new EventEmitter<dataType>();
...
<selector (alias)="someEvented($event)"></selector>
....
View Encapsulation
Emulated: 0
: default behavior. Use shimmed CSS that emulates the native behavior.Native: 1
: Use shadow roots. This works only if natively available on the platform.None: 2
ShadowDom: 3
: Use Shadow DOM to encapsulate styles.
usage:
1 | @Component({ |
Local References and @ViewChild
In template place a local reference on element then it will hold a reference to this element. you can use it directly only in current template context.
usage:
1 | <element #someRef ></element> |
if you want getting access to the template&DOM, using @ViewChild
.
1 | @ViewChild('someRef') someEle: ElementRef; |
ng-content and @ContentChild
projecting content into component dynamically. such as Tabs
1 | // component 'demo' template code |
A question: how demo component get access to the projected content? The answer is @ContentChild
1 | // same as above |
Lifecycle
- ngOnChanges: called after a bound input property changes.
- ngOnInit: called once the component is initialized.
- ngDoCheck: called during every change detection run.
- ngAfterContentInit: called after content(ng-content) has been projected into view.
- ngAfterContentChecked: called every time the projected content has been checked
- ngAfterViewInit: called after the component’s view(and child views) has been initialized.
- ngAfterViewChecked: called every time the view(and child views) have been checked.
- ngOnDestroy: called once the component is about to be destroyed.
Directives Deep Dive
Create Attribute Directive
1 | import { Directive, ElementRef } from '@angular/core'; |
usage:
1 | <p appBasicHighlight></p> |
Enhancing directive using the Renderer
:
1 | import { Directive, Renderer2 } from '@angular/core'; |
usage:
1 | <p appBetterHighlight></p> |
Why
Angular is not limited to running in the browser and for example also works with service worker. it is a better practice to use the renderer for dom access instead of accessing the native element directly.
HostListener and HostBinding
HostListener: Listen to Host Events.
HostBinding: Bind to the Host properties.
1 | import { Directive, RendererV2, ElementRef, HostListener, HostBinding } from '@angular/core'; |
Binding to Directive Properties
1 | import { Directive, RendererV2, ElementRef, HostListener, HostBinding, Input } from '@angular/core'; |
1 | <p hoverHighlight [defaultColor]="'yellow'" [highlightColor]="'red'">just a demo here!</p> |
what happens behind Structural Directive
As you know angular structual directive prefix with a star(*). ng-template
is a element that itself not rendered and it define a template for angular to use(determine which to render).
1 | <div *ngIf="onlyOdd"><p>something</p></div> |
Create Structual Directive like *ngIf
we will create our owned structual directive with the same functionality as *ngIf
.
1 | ({ |
usage:
1 | <div *appUnless="false"><p>some thing.</p></div> |