- Class that controls a view
-
Lifecycle Hooks in Order
- constructor
- ngOnChanges
- ngOnInit
- ngDoCheck
- ngDoAfterContentInit
- ngDoAfterContentChecked
- ngAfterViewInit
- ngAfterViewChecked
- ngOnDestroy
|
- This is equivalent to .NET web forms code-behind page
- Recommended for strong typing on editors that support it but not required is for a component to implement the hook interface. The name of the interface is the same as the hook minus the “ng” prefix. For example a component that needs to use the ngOnInit hook should be written as `Component1 implements OnInit`.
- Use case for every hook [https://angular.io/guide/lifecycle-hooks](https://angular.io/guide/lifecycle-hooks)
- Goes into the “declarations” argument of the @NgModule decorator
|
@HostBinding - sets a property to the host element which is the custom HTML tag specified in the `selector` (host) component property
|
export class ArticleComponent implements OnInit {
@HostBinding('attr.class') cssClass = 'row';
...
|
@HostListener - allows you to subscribe to the events of the DOM element.
|
@HostListener('click') displayMessage(): void {
alert(this.message);
}
Talking to the DOM directly is not considered best practice
@HostListener will be triggered for every HTML element if you have multiple root nodes in your templates like below
|
Content projection using ng-content allows you to inject dynamic markup in your template
|
// component file
@Component({
selector: 'home',
template: `
<h1>Title</h1>
<ng-content></ng-content>
`
})
// templateUrl file
<home>
<p>Hello World</p>
</home>
|
Component Lifecycle Hooks in order of execution:
- OnChanges
- OnInit
- DoCheck
- AfterContentInit
- AfterContentChecked
- AfterViewInit
- AfterViewChecked
- OnDestroy
|
- OnChanges is called every time a component’s @Input property changes
- DoCheck checks for any component property. Use this for changes that Angular wouldn’t catch like nested object properties. Avoid using OnChanges and DoCheck together because you’ll be calling 2 hooks for every change.
- OnChanges, DoCheck, AfterContentChecked, and AfterViewChecked are all called every change detection
|
Angular’s default change detection uses the Zones library
|
- Angular has a top-down execution for change detection. A component change anywhere in a dependency tree will trigger change detection for the entire tree.
|
Angular offers Default and OnPush ChangeDetectionStrategy for component bindings
|
|
- Push/pull data mapping between template and the component members
|
- 4 syntax forms
- {{ value }} : component property binding, outputs to the DOM
- [property]=“value” : component property binding for passing “value” down to a child component for outputting to the DOM
- (event)=“functionName(argument)” : event binding for calling a component function
- [(ngModel)]=”model.property” : event and property binding useful for form submissions
|
@Input - allows data to flow from the binding expression (template) into the directive (component).
|
- If you need to pass a value/object from the template into the component class, add a property to the template that matches the component class member. Whatever value you set will now be available inside the component class
Template:
<!-- myapp.component.html -->
<myapp [myData]="myDataModel"></myapp>
Component Class:
export class MyAppComponent {
// this is now available everywhere in this class
@Input() myData: MyDataClass
}
- brackets denote input. The value you assign to it will be used by the component property
|
@Output - expose event producers, such as EventEmitter objects. An output property streams an event “out” of the component
|
- Native events such as
click and keyup can be easily handled like so
<!-- Template -->
<button (click)="decrease()">Decrease</button>
<!-- Component -->
export class MyAppComponent {
click():void { return ‘hello’; }
}
- parenthesis denote output. This sends data out of your component for other components to listen to. These are your event handlers
- If you want to send a custom event when a DOM action is triggered, you have to use
EventEmitter . You set it up inside your component. You then listen for a native event and call the EventEmitter.emit() method after to broadcast it.
Template for MyComponent
<button (click)=”clickHandler” />
MyComponent
@Component({ selector: ‘my-component’ })
export class MyComponent {
clickCount: number = 0;
@Output() onEvent = new EventEmitter<number>();
clickHandler():void{
onEvent.emit(clickCount++);
}
...
OtherComponent
@Component({
selector: `other-component`,
template: `
<div>
<my-component (onEvent)=otherCompHander($event) />
</div>
`
})
export class OtherComponent({
otherCompHandler(count:number):void{
console.log(count);
}
})
|
Dependencies:
- ‘@angualr/router’ module
- template
- [routerLink] attribute
-
OR { provide: APP_BASE_HREF, useValue: '/' } as a provider
|
- You’ll typically import
{RouterModule, Routes, ActivatedRoute} from @angular/module
<router-outlet /> in your view is where the route components will be rendered. You can have multiple router outlets in your view with a caveat that it has to have a name attribute that you can target in your route configuration.
[routerLink]=[‘/about’] is a directive you can use in your Anchor tags to resolve the url of your application. Note that the value of routerLink is an array for additional parameters like in cases where the url is parameterized.
- The base href section is used for links with relative paths
|
Url Parsing strategies:
- HashLocationStrategy - hash url style
- PathLocationStrategy - html5 default using
pushState
|
Sample Code:
@NgModule({
...
providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy },
{ provide: APP_BASE_HREF, useValue: '/' } // <--- this right here
]
})
|
Import ActivatedRoute for handling dynamic urls and query string parameters.
|
- Use
activatedRoute.params[‘id’] to get the values from a route like /product/:id
- Use
activatedRoute.queryParamMap( params => params.get(‘key’ ) for querystring parameters
|
Import `CanActivate` from ‘@angular/router` for restricted routes
|
Guarding routes that are behind a login can be configured as { path: ‘admin’, component: ‘’, canActivate: [ LoggedInGuard ] } , where the authentication class structure looks like below
@Injectable()
export class LoggedInGuard implements CanActivate {
canActivate(
...
}
}
|
- Application of the Observer and Iterator pattern
- An observer subscribes to an Observable. An Observable emits items or sends notifications to its observers by calling the observers’ methods -
next , error and complete .
|
- Angular moved from Promises to Observables because the former lacks retry and cancellation mechanisms
- An observable remains unhandled until an element subscribes to it
|
Outputting data to the template:
https://auth0.com/blog/making-use-of-rxjs-angular/
|
- When dealing with an Observable say for an AJAX request, you can use the
async pipe to output the Observable value in your template. It will update the template once data has been extracted from the Observable
- The alternative is to
subscribe to the Observable, inside the callback function you can grab the value and assign it to your component property
|
Hot or Cold Observable
|
- In the context of an AJAX request if you have 3
subscribe s to an Observable, the AJAX request will issue 3 network calls (Cold Observable). To avoid doing this if you only need 1 network request, call the share() method (Hot Observable) to limit it.
|