Building  Large-Scale Web Applications with Angular
上QQ阅读APP看书,第一时间看更新

Integrating WorkoutAudioComponent

While we have componentized the audio playback functionality into WorkoutAudioComponent, it is and always will be tightly coupled to the WorkoutRunnerComponent implementation. WorkoutAudioComponent derives its operational intelligence from WorkoutRunnerComponent. Hence the two components need to interact. WorkoutRunnerComponent needs to provide the WorkoutAudioComponent state change data, including when the workout started, exercise progress, workout stopped, paused, and resumed.

One way to achieve this integration would be to use the currently exposed WorkoutAudioComponent API (stop, resume, and other functions) from WorkoutRunnerComponent.

Something can be done by injecting WorkoutAudioComponent into WorkoutRunnerComponent, as we did earlier when we injected MyAudioDirective into WorkoutAudioComponent.

Declare the WorkoutAudioComponent in the WorkoutRunnerComponent's view, such as:

<div class="row pt-4">...</div>
<abe-workout-audio></abe-workout-audio>

Doing so gives us a reference to the WorkoutAudioComponent inside the WorkoutRunnerComponent implementation:

@ViewChild(WorkoutAudioComponent) workoutAudioPlayer: WorkoutAudioComponent; 

The WorkoutAudioComponent functions can then be invoked from WorkoutRunnerComponent from different places in the code. For example, this is how pause would change:

    pause() { 
      clearInterval(this.exerciseTrackingInterval); 
      this.workoutPaused = true; 
      this.workoutAudioPlayer.stop(); 
    }

And to play the next-up audio, we would need to change parts of the startExerciseTimeTracking function:

this.startExercise(next); 
this.workoutAudioPlayer.onExerciseChanged(new ExerciseChangedEvent(next, this.getNextExercise()));

This is a perfectly viable option where WorkoutAudioComponent becomes a dumb component controlled by WorkoutRunnerComponent. The only problem with this solution is that it adds some noise to the WorkoutRunnerComponent implementation. WorkoutRunnerComponent now needs to manage audio playback too.

There is an alternative, however.

WorkoutRunnerComponent can expose events that are triggered during different times of workout execution, such as workout started, exercise started, and workout paused. The advantage of having WorkoutRunnerComponent expose events is that it allows us to integrate other components/directives with WorkoutRunnerComponent using the same events. Be it the WorkoutAudioComponent or components we create in future.