Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2: Using routes, how to display the navigation bar after successfully logged in?

Tags:

I'm trying to show the navigation bar, once the user successfully do.

For example:

How To Change "showMenu" property in "AppComponent" inside the "LoginComponent"? Important: I am using routes.

app.ts:

@Component({   selector: 'app',   template: `<div *ngIf="showMenu">                <fnd-menu-nav></fnd-menu-nav>              </div>              <router-outlet></router-outlet>               `,   directives: [ROUTER_DIRECTIVES, MenuNavComponent] }) @RouteConfig([   { path: '/login', name: 'Login', component: LoginComponent, useAsDefault: true },   { path: '/welcome', name: 'Welcome', component: WelcomeComponent } ]) export class AppComponent {   public showMenu : boolean; } 

login.component.ts:

@Component({   selector: 'fnd-login',   templateUrl: './fnd/login/components/login.component.html',   providers: [LoginService] }) export class LoginComponent {   /* .. other properties */    constructor(private _router: Router, private _loginService: LoginService ) {   }   /* .. other methods  */   /* .. other methods  */     private onLoginSuccessfully(data : any) : void {     /* --> HERE: Set showMenu in AppComponent to true. How? */     this._router.navigate(['Welcome']);    } } 

Or this design is not the best way to solve it?

like image 743
NereuJunior Avatar asked Apr 16 '16 13:04

NereuJunior


People also ask

Which component should be used for displaying routes?

RouterLink. The RouterLink is a directive that binds the HTML element to a Route . Clicking on the HTML element, which is bound to a RouterLink , will result in navigation to the Route . The RouterLink may contain parameters to be passed to the route's component.

What is router navigate?

In Angular, RouterLink is a directive for navigating to a different route declaratively. Router. navigate and Router. navigateByURL are two methods available to the Router class to navigate imperatively in your component classes.

How does angular implement navigation?

Inject ActivatedRoute into the constructor() by adding private route: ActivatedRoute as an argument within the constructor's parentheses. ActivatedRoute is specific to each component that the Angular Router loads. ActivatedRoute contains information about the route and the route's parameters.


1 Answers

I recently did something similar and here is how I did it. First, you need to create a NavBarComponent at the root of your app. And in the NavBarComponent you reference (what I call) a GlobalEventsManager which is a service that you inject where you need it.

Here is a look at the GlobalEventsManager:

import { Injectable } from '@angular/core';  import { BehaviorSubject } from "rxjs/BehaviorSubject";  import { Observable } from "rxjs/Observable";    @Injectable()  export class GlobalEventsManager {        private _showNavBar: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);      public showNavBarEmitter: Observable<boolean> = this._showNavBar.asObservable();        constructor() {}        showNavBar(ifShow: boolean) {          this._showNavBar.next(ifShow);      }      }

Now you inject the GlobalEventsManger service into your login component (something like this)

import {GlobalEventsManager} from "./../GlobalEventsManager";    @Component({    selector: 'fnd-login',    templateUrl: './fnd/login/components/login.component.html',    providers: [LoginService]  })  export class LoginComponent {    /* .. other properties */      constructor(private _router: Router, private _loginService: LoginService, private globalEventsManager: GlobalEventsManager) {    }    /* .. other methods  */    /* .. other methods  */        private onLoginSuccessfully(data : any) : void {      /* --> HERE: you tell the global event manger to show the nav bar */      this.globalEventsManger.showNavBar(true);      this._router.navigate(['Welcome']);      }  }
In your NavBarComponent you subscribe to the showNavBar Event Emitter:

import {Component, OnInit} from "@angular/core";  import {GlobalEventsManager} from "../GlobalEventsManager";  @Component({      selector: "navbar",      templateUrl: "app/main/topNavbar/TopNavbar.html"  })    export class TopNavbarComponent  {      showNavBar: boolean = false;          constructor(private globalEventsManager: GlobalEventsManager) {           this.globalEventsManager.showNavBarEmitter.subscribe((mode)=>{                            this.showNavBar = mode;          });                }       }
use *ngIf="showNavBar" in the template HTML to hide/show the Nav bar.

Your app component then looks something like this:

@Component({    selector: 'app',    template: `<navbar></navbar>               <router-outlet></router-outlet>                `  })  export class AppComponent {    //This doesn't belong here --> public showMenu : boolean;  }

Also the GlobalEventsManager must be registered when you boot the app:

import { GlobalEventsManager } from './GlobalEventsManager';  import { TopNavbarComponent } from './TopNavbarComponent';    @NgModule({      bootstrap: [App],      declarations: [          App,          TopNavbarComponent      ],      imports: [          BrowserModule      ],      providers: [GlobalEventsManager]  })  export class AppModule {  }

That should do it.

UPDATE: I have updated this answer to reflect the more accepted way of using events outside of a component, ie in a service; which entails using BehaviorSubject/Observable instead of EventEmitter

like image 51
brando Avatar answered Sep 20 '22 16:09

brando