Using Events

After discussing the method of the parent component way to send data to its child components, we need to pass data in the opposite direction. Because the child component doesn’t know which component is going to contain it, it cannot bind to any member of its containing component. Therefore, the only way a child component can communicate with its parent is through Events.

For that matter we will use another decorator named Output and a class named EventEmitter for launching the event.

The EventEmitter is a generic type where the type parameter is the type of the argument sent with the event.

EventEmitter class

We’ve previously dicussed how to use this class, so now we will elaborate a little more about that class.

This class extends the Subject class from rx.js, which extends the Observable class of the same module. You may read more about that in Chapter 10, Change Detection.

Whenever you use the event on your HTML template you actually subscribe on the event, and your handler is added to its observers array. All observers are called when using the event’s emit() method.

Built in Events

As discussed on the Data Binding section, the event is bound by round brackets. There are many built in events, however, on our component we are going to create a custom event.

We will firs add a textbox to the child component and bind it to another property.

Second, we will create an EventEmitter typed member that will invoke an event whenever the newly created property is changed.

Third, we will bind the change event of the input element to a method on the child component in that method, where the event we’ve just created will be launched.

import{Component,Input,Output}from'@angular/core';@Component({selector:'child-component',template:`<h2>{{componentName}}</h2><inputtype="text"[(ngModel)]="comopnentValue"(change)="componentValueChanged()"/>`})exportclassChildComponent{@Input()componentName:string;@Output()onComponentValueChange:EventEmitter<any>=newEventEmitter<any>();componentValue: string;componentValueChanged(){this.onComponentValueChange(this.componentValue);}}

After doing that, on our main component all we have to do is to bind to the newly created custom event. We will add another string member to our main component class, named childComponentValue and bind it to a span’s inner text on our main component, so the changes will be shown on the screen.

/*Import the child component */import{ChildComponent}from'path/to/childComponent';@Component({selector:'main-component',template:`<h1>MainappComponent</h1><!--usingtheinnercmponenthere--><child-component[componentName]="childComponentName "(onComponentValueChange)="childComponentValueChange($event)"></child-component><!--showingchildcomponentvalueonthemaincomponent--><span>{{childComponentValue}}</span>`/*Putting the child compont type in our directives*/directives:[Childomponent]})exportclassMainComponent{childComponentName: string;childComponentValue: string;constructor(){this.childComponentName="child component";}childComponentValueChange(componentValue){this.childComponentValue=componentValue;}}

Now we have created a custom event that will be fired from the child component to its parent whenever the componentValue is changed on the child component.

Component lifecycle

A component has its own lifecycle events so we can hook them and right the code that will run whenever these events occur. Angular manages the lifecycle itself so we can have our custom code.

For hooking an event our component class should implement the corresponding interface. Angular core has a corresponding interface for each event. That interface has a method with the ng prefix and the event name (for example ngOnInit , ngOnDestroy etc.).

Here’s a list of lifecycle hooks

  1. OnInit occurs after the compoenent is being initalized
  2. OnDestroy occurs before a component is destroyed
  3. OnChanges occurs on every change that occurs in the component data
  4. DoCheck extends the Onchanges handler, and when DoCkeck is implemented, it overrides the default change detection algorithm
  5. AfterContentInit occurs after content init

In order to hook one of these lifecycle events you should implement its corresponding interface (inerface names are listed above). Each interface has a method that will handle the lifecycle event.

 

Components hold the UI structure and behavior of our application. They can be built on the HTML5 web component wherever the browser supports them. A component can contain another component and bind data to it by its @Input decorated members. The inner component can send messages to its container component by using custom events. Cutom events are written with EventEmitter<type> type members decorated with the @output decorator.