Adding interactivity to the component

Angular provides top-notch support for events through a declarative interface. This means it is easy to hook up events and have the point to method. It's also easy to bind data to different HTML attributes, as you are about to learn.

Let's first modify our template definition:

@Component({
selector: 'timer',
template: `
<h1>{{ minutes }}: {{ seconds }} </h1>
<p>
<button (click)="togglePause()"> {{ buttonLabel }}</button>
</p>
`
})

We used a multiline text string! ECMAScript 6 introduced the concept of
template strings, which are string literals with support for embedded expressions, interpolated text bindings, and multiline content. We will look into them in more detail in Chapter 3, Introducing TypeScript.

In the meantime, just focus on the fact that we introduced a new chunk of HTML that contains a button with an event handler that listens to click events and executes the togglePause() method upon clicking. This (click) attribute is something you might not have seen before, even though it is fully compliant with the W3C standards. Again, we will cover this in more detail in Chapter 4, Implementing Properties and Events in Our Components. Let's focus on the togglePause() method and the new buttonLabel binding. First, let's modify our class properties so that they look like this:

export class TimerComponent {
minutes: number;
seconds: number;
isPaused: boolean;
buttonLabel: string;
// rest of the code will remain as it is below this point
}

We introduced two new fields. The first is buttonLabel, which contains the text that will later on be displayed on our newly-created button. isPaused is a newly-created variable that will assume a true/false value, depending on the state of our timer. So, we might need a place to toggle the value of such a field. Let's create the togglePause() method we mentioned earlier:

togglePause() {
this.isPaused = !this.isPaused;
// if countdown has started
if(this.minutes < 24 || this.seconds < 59) {
this.buttonLabel = this.isPaused ? 'Resume' : 'Pause';
}
}

In a nutshell, the togglePause() method just switches the value of isPaused to its opposite and then, depending on such a new value and whether the timer has started (which would entail that any of the time variables has a value lower than the initialisation value) or not, we assign a different label to our button.

Now, we need to initialize these values, and it seems there is no better place for it. So, the reset() function is the place where variables affecting the state of our class are initialized:

reset() {
this.minutes = 24;
this.seconds = 59;
this.buttonLabel = 'Start';
this.togglePause();
}

By executing togglePause() every time, we reset it the to make sure that whenever it reaches a state where it requires to be reset, the countdown behavior will switch to the opposite state it had previously. There is only one tweak left in the controller method that handles the countdown:

private tick() {
if(!this.isPaused) {
this.buttonLabel = 'Pause';
if(--this.seconds < 0) {
this.seconds = 59;
if(--this.minutes < 0) {
this.reset();
}
}
}
}

Obviously, we do not want the countdown to continue when the timer is supposed to be paused, so we wrap the whole script in a conditional. In addition to this, we will want to display a different text on our button whenever the countdown is not paused and once again when the countdown reaches its end; stopping and then resetting the Pomodoro to its initial values will be the expected behavior. This reinforces the need of invoking the togglePause function within resetPomodoro.

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

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