As a final step, we also need to refactor our navigation components to rely on the router. So far, we used our own routing that was implemented in a complex nested-navigation component structure. We can simplify this a lot using the Angular router.
Let's start with the smallest component first, and edit our NavigationItem
component template in the lib/navigation/navigation-section/navigation-item/navigation-item.html
file:
<a class="navigation-section__link" [class.navigation-section__link--active]="isActive()" [routerLink]="link">{{title}}</a>
Instead of controlling the link behavior ourselves, we now use the RouterLink
directive to generate a link that is based on the component link
input property. To set the active class on the navigation link, we still rely on the isActive
method on our component, and there's no change required in the template.
Let's look at the changes to the Component
class in the navigation-item.js
file:
... import {RouterLink} from '@angular/router/src/directives/router_link'; @Component({ selector: 'ngc-navigation-item', ... directives: [RouterLink] }) export class NavigationItem { @Input() title; @Input() link; @ViewChild(RouterLink) routerLink; isActive() { return this.routerLink ? this.routerLink.isActive : false; } }
Instead of relying on the Navigation
component to manage the active state of navigation items, we now rely on the RouterLink
directive. Each RouterLink
directive provides an accessor
property, isActive
, which tells us whether this specific route addressed by the router link is currently activated within the browsers URL. Using the @ViewChild
decorator, we can query for the RouterLink
directive in our view and then query the isActive
property to find out if the current navigation item is active or not.
Now, we only need to make sure that we pass the necessary items to the Navigation
component in our App
component in order to make our navigation work again.
The following code needs to be changed in the App
component constructor in the app.js
file:
this.projectsSubscription = projectService.change .subscribe((projects) => { this.projects = projects; // We create new navigation items for our projects this.projectNavigationItems = this.projects // We first filter for projects that are not deleted .filter((project) => !project.deleted) .map((project) => { return { title: project.title, link: ['/projects', project._id] }; }); });
By filtering and mapping the available projects, we can create a list of navigation items that contain a title
and link
property. The link
property contains a route link DSL that points to the project details route that is configured in the App
component router configuration. By passing an object literal as a sibling to the route name, we can specify some parameters along the route. Here, we simply set the expected projectId
parameter to the ID of the project in the projects list.
Now, our navigation components make use of the router to enable navigation. We got rid of our custom routing functionality in the Navigation
component, and we use router link DSL to create navigation items.