Building the 7 Minute Workout view

Most of the hard work has already been done while defining the model and implementing the component. Now, we just need to skin the HTML using the super-awesome data binding capabilities of Angular. It's going to be simple, sweet, and elegant!

For the 7 Minute Workout view, we need to show the exercise name, the exercise image, a progress indicator, and the time remaining. Replace the local content of the workout-runner.component.html file with the content of the file from the Git branch checkpoint2.2, (or download it from http://bit.ly/ng6be-2-2-workout-runner-component-html). The view HTML looks as follows:

<div class="row">
<div id="exercise-pane" class="col-sm">
<h1 class="text-center">{{currentExercise.exercise.title}}</h1>
<div class="image-container row">
<img class="img-fluid col-sm" [src]="'/assets/images/' +
currentExercise.exercise.image" />
</div>
<div class="progress time-progress row">
<div class="progress-bar col-sm"
role="progressbar"
[attr.aria-valuenow]="exerciseRunningDuration"
aria-valuemin="0"
[attr.aria-valuemax]="currentExercise.duration"
[ngStyle]="{'width':(exerciseRunningDuration/currentExercise.duration) *
100 + '%'}">
</div>
</div>
<h1>Time Remaining: {{currentExercise.duration-exerciseRunningDuration}}</h1>
</div>
</div>

WorkoutRunnerComponent currently uses an inline template; instead, we need to revert back to using an external template. Update the workout-runner.component.ts file and get rid of the template property, then uncomment templateUrl, which we commented out earlier.

Before we understand the Angular pieces in the view, let's just run the app again. Save the changes in workout-runner.component.html and if everything went fine, we will see the workout app in its full glory:

The basic app is now up and running. The exercise image and title show up, the progress indicator shows the progress, and exercise transitioning occurs when the exercise time lapses. This surely feels great!

If you are having a problem with running the code, look at the Git branch checkpoint2.2 for a working version of what we have done thus far. You can also download the snapshot of checkpoint2.2 (a ZIP file) from this GitHub location:  http://bit.ly/ng6be-checkpoint-2-2 . Refer to the README.md file in the trainer folder when setting up the snapshot for the first time.

Looking at the view HTML, other than some Bootstrap styles, there are some interesting Angular pieces that need our attention. Before we dwell on these view constructs in detail, let's break down these elements and provide a quick summary:

  • <h1 ...>{{currentExercise.exercise.title}}</h1>: Uses interpolation
  • <img ... [src]="'/assets/images/' + currentExercise.exercise.image" .../>: Uses property binding to bind the src property of the image to the component model property currentExercise.exercise.image
  • <div ... [attr.aria-valuenow]="exerciseRunningDuration" ... >: Uses attribute binding to bind the aria attribute on div to exerciseRunningDuration
  • < div ... [ngStyle]="{'width':(exerciseRunningDuration/currentExercise.duration) * 100 + '%'}">: Uses a directive ngStyle to bind the style property on the progress-bar div to an expression that evaluates the exercise progress

Phew! There is a lot of binding involved. Let's dig deeper into the binding infrastructure.