Triggering routes imperatively
Perhaps, you would like to jump on our timer by selecting the task we want to work on. We have already set up a behavior that displayed a queued label whenever each task was picked for being done. We will leverage the same behavior to create a work on button that will redirect the user to the timer component.
First, let’s inject the Router
type as a dependency in our TasksComponent
module, so we can gain access imperatively to its methods. Since we already declared the ROUTER_PROVIDERS
symbol while bootstrapping the application, Angular 2 will take care of injecting the router type if properly declared in our component, so let’s do it. Add the following import statement at the top of the component, right after the existing ones:
app/tasks/tasks.component.ts
import { Router } from '@angular/router-deprecated';
Now, let’s update the constructor to inject the router type. We will mark the constructor as a private form so that it becomes privately available from the component members:
app/tasks/tasks.component.ts
...
constructor(
private taskService: TaskService,
private settingsService: SettingsService,
private router: Router) {
this.tasks = this.taskService.taskStore;
this.today = new Date();
this.queueHeaderMapping = settingsService.pluralsMap.tasks;
this.timerMinutes = settingsService.timerMinutes;
}
...
Now, let’s add a method right below the updateQueuedPomodoros()
method, which will lead the user imperatively to the task route upon executing it:
workOn(): void { this.router.navigate(['TimerComponent']); }
How do we execute it? Let’s introduce a new button in our table, next to the toggle task button at the last cell on each row, with a click handler pointing to the preceding method. The code is as follows:
app/tasks/tasks.component.html
<td> <button type="button" class="btn btn-default btn-xs" [ngSwitch]="task.queued" (click)="toggleTask(task)"> <template [ngSwitchWhen]="false"> <i class="glyphicon glyphicon-plus-sign"></i> Add </template> <template [ngSwitchWhen]="true"> <i class="glyphicon glyphicon-minus-sign"></i> Remove </template> <template ngSwitchDefault> <i class="glyphicon glyphicon-plus-sign"></i> Add </template> </button> <button type="button" class="btn btn-default btn-xs" *ngIf="task.queued" (click)="workOn()"> <i class="glyphicon glyphicon-expand"></i> Start </button> </td>
A convenient NgIf
directive will display the button only when required. We have included an icon for cosmetic purposes, but feel free to remove it or replace it by any other glyph of your choice.
Now reload the table, set out any task to be done, and click on the button that appears. Voila! You will be redirected to the timer to begin working on that task if desired.
Note
The navigate()
method of the new Router will expect a string containing the full path instead.
CSS hooks for active routes
We have seen how to turn any link or DOM element into a hyperlink pointing to a named route that instantiates a component. However, it would be great to provide some kind of visual cue about the active link at any given time. That is precisely one of the side features implemented in the routerLink
directive: whenever the route defined on a routerLink
directive becomes active (regardless of whether the user reached that route declaratively or imperatively), the element will be decorated with the router-link-active class. We can therefore introduce specific CSS definitions in our components’ style sheets to highlight if a specific link is active or not.
We will see all this functionality in action just by tweaking our top parent component a bit. Open the top root component controller class file and insert the following style sheet in hte
component decorator configuration:
app/app.component.ts
@Component({ selector: 'pomodoro-app', directives: [ROUTER_DIRECTIVES], providers: [SHARED_PROVIDERS, HTTP_PROVIDERS, ROUTER_PROVIDERS], styles: [` .router-link-active { font-weight: bold; border-bottom: 2px #d9534f solid; } `], templateUrl: 'app/app.component.html' })
Now reload the browser and click on any link or navigate to a task timer from the tasks table, keeping an eye on the visual state of the top nav bar. The active link will be properly enhanced with the styling we defined. If you inspect the code, you will see the router-link-active class rendered on the active link each time.