Input and output properties in action

The best way to grasp the concepts detailed in the earlier sections is by practice. In the first chapter, we learned how to build an application from scratch by using either Webpack or Angular-CLI to set up the project. As Angular-CLI is considered the standard way of setting up the project, let's use just that and scaffold ourselves a new project by typing:

ng new InputOutputDemo

At this point, we have a fully working project that we can easily serve up by typing ng serve

Let's quickly remind ourselves of the anatomy of an Angular project so we know what to do with all the new constructs we are about to create. The following files are of extra interest:

  • main.ts: This file bootstraps our application.
  • app/app.module.ts: This file declares our root module, any new constructs will have to be added to the declarations property of this module or you will need to add a dedicated module for those future constructs. It is generally recommended to have a dedicated module for new constructs we have.

In the previous bullet list, we mentioned the concept root module. We mentioned this concept to remind ourselves of Angular modules in general. An Angular module holds a bunch of constructs that belong together. You will recognize an Angular module by using the @NgModule decorator; the module itself is just a plain class. The @NgModule decorator takes an object literal as input and it is within this object literal that we register everything that belongs to the module.

As mentioned in the preceding bullet list, it is considered good practice to add a dedicated module for our new constructs, so let's do just that:

@NgModule({
declarations: []
})
export class InputModule {}

At this point, we are leaving the declarations property array empty. Once we have declared our component, we will add it to that array. 

This module doesn't belong to the application just yet, but it will need to be registered with the root module. Open up the app.module.ts file and add the newly created module to the import array, like so:

@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
InputModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Let's strip down the timer example that we saw in Chapter 1, Creating Our Very First Component in Angular, and discuss a simpler example. Let's have a look at the TimerComponent file and replace its contents with the following component class:

import { Component } from '@angular/core';

@Component({
selector : 'countdown-timer',
template : '<h1>Time left: {{seconds}}</h1>'
})
export class CountdownTimerComponent {
seconds: number = 25;
intervalId: any;

constructor() {
this.intervalId = setInterval(() => this.tick(), 1000);
}

private tick(): void {
if(--this.seconds < 1) {
clearInterval(this.intervalId);
}
}
}

Great! We have just defined a simple but highly effective countdown timer component that will count down to 0 from 25 seconds (do you see the seconds field up there? TypeScript supports the initialisation of members upon declaring them). A simple setInterval() loop executes a custom private function named tick() that decreases the value of seconds until it reaches zero, in which case we just clear the interval.

However, now we just need to embed this component somewhere, so let's create another component with no functionality other than acting as an HTML wrapper host for the previous component. Create this new component right after the CountdownTimerComponent class in the same file:

@Component({
selector: 'timer',
template: '<countdown-timer></countdown-timer>'
})
export class TimerComponent {}

As promised earlier, we will also add our newly created components to the declarations array of the module it belongs to, like so:

@NgModule({
declarations: [CountdownTimerComponent, TimerComponent]
})
export class InputModule {}

The reason for doing this in the first place is to ensure that these components are made available for one another, as is the case with CountdownTimerComponent being used inside the template of TimerComponent.

Components in Angular are basically directives with a view template. We can also find directives with no view, which basically add new functionalities to their host element, or they just act as custom elements without a UI that wraps other elements. Alternatively, they simply provide further functionalities to other components by means of their API.

We will explore directives in detail in the next chapter and also throughout the book. You must be wondering why we have created this host or parent TimerComponent  component with no implementation. Soon, we will flesh it out with some more features, but for now let's use it as a proof of concept for how to initiate a component tree.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset