Home > Enterprise >  Open and Close sidenav when click on button from another component in angular
Open and Close sidenav when click on button from another component in angular

Time:12-26

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) menas open sidebar component

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

navbar.component.html

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

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

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

  <!-- Login & Menu  -->
    <div >
      <img src="../../../assets/login_black.png" alt=""><span>login</span>
      <span >  <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 >
  <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

CodePudding user response:

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:

CodePudding user response:

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'>

  • Related