-2

how to open sidebar when click on button. i have two component 1.navbar 2.sidebar and navbar html file in have a some button like menu login when click on menu button to open sidebar (using angular material sidebar)

  • layout--
    │ ├── navbar
    │ └── sidebar
    |---services
    └── app.module

navbar.component.html

<!-- <app-sidebar></app-sidebar> -->

<div class="navbar">
<!-- sync logo -->
<div class="item">
  <img src="../../../assets/logo.png" alt="">
</div>

<!-- Search bar     -->
    <div class="item2">
        <input  class="search_bar" type="text" name="" value="" 
     placeholder="Search talent by skills ">
    </div>

  <!-- Login & Menu  -->
    <div class="item3">
      <img src="../../../assets/login_black.png" alt=""><span>login</span>
      <span class="menu">  <button mat-button (click)="toggleMenu()">menu</button></span>
    </div>

</div>

navbar.component.ts

import { Component, OnInit,Output,EventEmitter } from'@angular/core';
// import {SideNavService} from '../../side-nav.service'
@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit {
  @Output() menuState:EventEmitter<any> = new EventEmitter();


  constructor() { }

  open:boolean;
  showMenu = false;

  toggleMenu() {
    console.log("inside togglemenu");
    this.showMenu =!this.showMenu;
    this.menuState.emit(this.showMenu)
  }

  ngOnInit(): void {
  }
    emit(){
    }
}

sidebar.component.html

 <mat-drawer-container class="example-container">
  <mat-drawer #sidenav mode="over" opened="true" position='end' >Drawer content</mat-drawer>
  <mat-drawer-content>Main content
  <!-- <button type="button" (click)="sidenav.toggle()" name="button"></button> -->
  </mat-drawer-content>
</mat-drawer-container>

sidebar.component.ts

import { Component, OnInit,Input ,OnChanges} from '@angular/core';

@Component({
  selector: 'app-sidebar',
  templateUrl: './sidebar.component.html',
  styleUrls: ['./sidebar.component.scss']
})


export class SidebarComponent implements OnInit ,OnChanges{
@Input() subMenuState:any;
  constructor() { }

  opened:boolean;
  showMenu = true;

  ngOnInit(): void {}

  ngOnChanges(){
    console.log("inside ngOnChanges with subMenuState: ",this.subMenuState);
    this.showMenu = this.subMenuState;
  }

}

enter image description here

i want like this

enter image description here

Robin Chauhan
  • 71
  • 4
  • 12
  • In the navigation.component.ts, you have a variable named "showMenu" and you also have a similar variable in sidebar component. How are you planning to transfer values between these two variables across components? Can you explain what tutorial/video you are following here? – Ashish Deora Dec 26 '21 at 08:47
  • @AshishDeora i try many stackblitz example and now i marge two component to single component that is working but what i try to do this . that is not working – Robin Chauhan Dec 26 '21 at 14:13
  • Ideally, both the child components should be wrapped into a single parent component. You could then transfer data between the two components using observables (as component variable or service). – Ashish Deora Dec 26 '21 at 17:54
  • do you still have a requirement to have both of them in separate component? Ideally you should have them separated so that they can be reused into the project wherever needed. – Ashish Deora Dec 26 '21 at 17:54
  • @AshishDeora yes require to separate the both component . now i'm using both component in single component that's is working and i know if use services that would be work but i don't know how to do this . it's helpful if you give me example with working code – Robin Chauhan Dec 27 '21 at 09:49
  • Are you using angular material? Check this link and let me know if this is helpful - https://stackoverflow.com/questions/38209713/how-to-make-a-responsive-nav-bar-using-angular-material-2 – Ashish Deora Dec 28 '21 at 09:28
  • @AshishDeora it's working using services thanks for quick response – Robin Chauhan Dec 28 '21 at 09:44

2 Answers2

0

Use named router outlet for the sidebar. In such way you'll be able to control the sidebar via the router. If you add state management, it will be even more neat.

See example here https://github.com/rfprod/nx-ng-starter/blob/main/apps/client/src/app/app-routing.module.ts#L15

Refs:

rfprod
  • 231
  • 2
  • 8
0

Create a service handling user interface settings and state and emitting them as rxjs BehaviorSubjects in every component where you need that information.

Example of a UI state management service:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

// This interface can be modified and extended to include also other information, for example darkMode etc. 
interface UIState {
  sideNavOpen: boolean;
}

@Injectable({
  providedIn: 'root',
})
export class UIManagerService {

  private _uiState: UIState = {
    sideNavOpen: false
  };

   // Observable emitting UI state values for depending components.
  private uiState$: BehaviorSubject<UIState> = new BehaviorSubject(
    this._uiState
  );

  // private method used by this service to set the UI state and update BehaviorSubject
  private set uiSettings(state: UIState) {
    this.uiState$.next(state);
  }

  // Components use this getter method to access the UI State
  public get uiSettings(): UIState {
    return this.uiState$.getValue();
  }

  // Call this public method to change the sidenav status. Write additional logic if needed
  public sideNavToggle(): void {
    this._uiState.sideNavOpen = !this._uiState.sideNavOpen;
    this.uiSettings = this._uiState; // call setter to store and emit changes
  }
}

To use the service, you inject it into the components as described in Angular documentation and add a couple of methods to use it:

constructor(private ui: UIManagerService) {}

get uiState(): UIState {
    return this.ui.uiState;
  }

sideNavToggle(): void {
    this.ui.sideNavToggle();
  }

For example you can change your code:

<mat-drawer #sidenav mode="over" opened="true" position='end'>

to

<mat-drawer #sidenav mode="over" [opened]="this.uiState.sideNavOpen" position='end'>

Marko Eskola
  • 717
  • 4
  • 11