Refactoring navigation

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.

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

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