Skip to content Skip to sidebar Skip to footer

In Angular2 How Do You Change A Sidebar Based On The Active Route?

I'm writing an SPA using Angular 2 (RC5) and Typescript. I have a main navbar on top (using Bootstrap 4 Alpha 3), and a custom-designed sidebar. Here's a pic: The intention here

Solution 1:

I've done the same thing and here is how I solved it.

  1. Created the menu in the top-most app component
  2. Created a service and kept a common routing table in the service
  3. Created a subscribable subject stream for changing the route
  4. Subscribed to that stream from the component where the menu resides
  5. Issue subcription.next from the current component which sets the selected route in the component with the menu.

You can achieve this with other type of component interactions. Here is more info on that from the Angular 2 docs: https://angular.io/docs/ts/latest/cookbook/component-communication.html

Solution 2:

Here's one possible solution.

Since each of your three apps is meant to be completely separate (as you've defined it), you could make a completely independent 'SideBarComponent' that you can reuse in each app.

Since you can give a component any information you want with @Input() variables, you can provide it the list of labels, links, and icons it needs. For example:

EquipmentComponent.ts

sideBarLinks: any = { proboard: [
  { label: 'Home', link: '/proboard', icon: 'fa-home'},
  { label: 'Candidates', link: '/proboard/candidates', icon: 'fa-users'},
  { label: 'New', link: '/proboard/candidate/new', icon: 'fa-new-user; } ]
}

EquipmentComponent.html

<side-bar [buttons]='sideBarLinks'></side-bar>

SideBarComponent.ts

@Input()
buttons: any;

SideBarComponent.html

// Use 'buttons' to construct your buttons in the sidebar. Possibly using an ng repeater in this template.

Even if you don't end up implementing this exactly, I hope this gets you thinking in the direction of using reusable components with Angular 2.

Hopefully this is helpful!

Here's more than everything you would need to know about component interactions: https://angular.io/docs/ts/latest/cookbook/component-communication.html.

Solution 3:

2 possible ways

1 - In sidebar component, subscribe to router changes, but you will end up using *ngIf

@Input()data: any;

constructor(private router: Router) {
    router.changes.subscribe((val) => {
        if(val === 'noSidebarRoute'){
            this.navButtons= false;
        }
        else {
            this.navButtons= navData;
        }
    })
}

then in parent component template

@Component({
    selector: 'parent',
    template: `<side-bar [data]='navData'></side-bar>`
});

export class Parent{

navData = [
     { proboard: [
       { label: 'Home', link: '/proboard', icon: 'fa-home'},
       { label: 'Candidates', link: '/proboard/candidates', icon: 'fa-users'},
       { label: 'New', link: '/proboard/candidate/new', icon: 'fa-new-user; }
     ]},
     { tracker: [...] },
     { equipment: [...] }
]}

2 - in your app component (or sidebar parent component), use resolver.resolveComponent to dynamically add the sidebar component to your app, this way you won't be using data binding (*ngIf).

sidebarCmpRef:ComponentRef<any>;

constructor(private router: Router,
            private viewContainerRef:ViewContainerRef,
            private resolver:ComponentResolver) {

    router.changes.subscribe((val) => {
        if(val === 'noSidebarRoute'){
            if(this.sidebarCmpRef){
               this.sidebarCmpRef.destroy();
               this.sidebarCmpRef
            }
        }
        else{
            this.AddSidebar();
        }
    })
}

AddSidebar(){
    if(!this.cmpRef){
        this.resolver.resolveComponent(<Type>SideBar)
          .then((factory:ComponentFactory<any>) => {
            this.cmpRef = this.viewContainerRef.createComponent(factory);
            this.cmpRef.instance.buttons= navData;
        });
    }
}

Solution 4:

I would prefer to go with angular basic approach i.e loading children inside the routes.

Define your main.route as follows

import { NgModule } from'@angular/core';
import { Routes, RouterModule } from'@angular/router';
import { PageNotFoundComponent } from'./shared/components/pagenotfound.component';

exportconstappRoutes: Routes = [
  {
    path: 'tracker',
    loadChildren: 'app/tracker/module#trackermodule',
  },
  {
    path: 'proboard',
    loadChildren: 'app/proboard/module#proboard',
  },
 {
    path: 'equiment',
    loadChildren: 'app/equiment/module#equiment',
  },
  {
    path: '**',
    component: PageNotFoundComponent
  }
];

@NgModule({
    imports: [RouterModule.forRoot(appRoutes)],
    declarations: [
        PageNotFoundComponent
    ],
    exports: [RouterModule]
})

exportclassAppRouterModule {
}

then in your child/sub-module routing configuration should be

import { RouterModule } from'@angular/router';
import {  CssComponent } from'./view';
import { RadioAndCheckBoxComponent } from'./radio-and-checkbox/view';

exportconstRouteComponents = [
  CssComponent
];

exportconstRoutes = RouterModule.forChild([
  {
    path: '',
    component: equimentComponent,
    children: [
      {
        path: 'Home',
        component: HomeComoponent
      },
      {
        path: 'Candidates',
        component: CandidatesComoponent
      }
    ]
  }
]);

Solution 5:

I have same situation (Main Menu Links and their respected sub menu items), I have done this in following manner.

Inside the root component (app.component.ts) constructor, I subscribe to router events, and based on the redirect route URL, I hide and show the Main application sub menus. Here is code:

this.router.events.subscribe(event => {
  if (event instanceof NavigationEnd) {

    this.currentUrl = event.urlAfterRedirects;
    console.log(event.urlAfterRedirects);

    if (this.currentUrl.includes("/MainMenuLink1")) {
      this.link1SubMenu = true;
      this.link2SubMenu = false;
    } elseif (this.currentUrl.includes("/MainMenuLink2")) {
   this.link2SubMenu = true;
      this.link1SubMenu = false;
    }

  }
});

And based on that [link1SubMenu] boolean values, I show and hide the Sub menu in app.component.html using *ngIf='link1SubMenu'

It needs to be refactored, but this is quick win.

Post a Comment for "In Angular2 How Do You Change A Sidebar Based On The Active Route?"