web-dev-qa-db-fra.com

Ouvrir / fermer le sidenav d'un autre composant

J'utilise angular (dernière version) et angular matériel).

Il y a 3 composants:

  • header.component, dans lequel il y a un bouton de commande pour right-sidenav
  • rigth-sidenav.component, dans lequel se trouve le right-sidenav
  • sidenav.component (c'est le menu principal de gauche), ce composant appelle header.component, right-sidenav.component et content

Comment ouvrir/fermer sidenav à partir d'un autre composant? (dans mon cas, le bouton est dans header.component).

J'ai essayé l'option suivante (mais j'ai eu l'erreur: TypeError: this.RightSidenavComponent.rightSidenav n'est pas défini):

header.component.html

<button mat-button (click)="toggleRightSidenav()">Toggle side nav</button>

header.component.ts

import { Component } from '@angular/core';
import { RightSidenavComponent } from '../right-sidenav/right-sidenav.component';
@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent {

    constructor(public RightSidenavComponent:RightSidenavComponent) {   }
    toggleRightSidenav() {
        this.RightSidenavComponent.rightSidenav.toggle();
    }

}

sidenav.component.html

<mat-sidenav-container class="sidenav-container">
    <mat-sidenav #sidenav mode="side" opened="true" class="sidenav"
                 [fixedInViewport]="true"> Sidenav  </mat-sidenav>
    <mat-sidenav-content>
        <app-header></app-header>
        <router-outlet></router-outlet>
        <app-right-sidenav #rSidenav></app-right-sidenav>
    </mat-sidenav-content>
</mat-sidenav-container>

sidenav.component.ts

import { Component, Directive, ViewChild } from '@angular/core';
import { RightSidenavComponent } from '../right-sidenav/right-sidenav.component';

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

export class SidenavComponent {

    @ViewChild('rSidenav') public rSidenav;
    constructor(public RightSidenavComponent: RightSidenavComponent) {
        this.RightSidenavComponent.rightSidenav = this.rSidenav;
    }

}

right-sidenav.component.html

<mat-sidenav #rightSidenav mode="side" opened="true" class="rightSidenav"
             [fixedInViewport]="true" [fixedTopGap]="250">
    Sidenav
</mat-sidenav>

right-sidenav.component.ts

import { Component, Injectable } from '@angular/core';

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

@Injectable()
export class RightSidenavComponent {

    public rightSidenav: any;

    constructor() { }

}

exemple non fonctionnel avec code stackblitz

30
Denis

Si vous travaillez dans Angular 9+ N'oubliez pas d'ajouter un paramètre de static: true Dans @ViewChild Comme:

@ViewChild('rightSidenav', {static: true}) sidenav: MatSidenav;

Vous pouvez voir mon code travailler sur Angular 9 ici:

https://stackblitz.com/edit/angular-kwfinn-matsidenav-angular9

1
amolinaoOT

Pour ajouter à la réponse d'Eldho, vous pouvez désactiver les animations pour un véritable effet de masquage.

    <mat-sidenav #leftbar opened mode="side" class="ng-sidenav" [@.disabled]="true">
0
Jonathan

Bien que les gens ci-dessus aient déjà répondu, mais je crois que ma solution est plus simple lorsque je me suis résolu.

Vous devez disposer d'un service intermédiaire pour prendre en charge les deux composants.

Disons que ce service est NavService, le code ci-dessous va dans NavService:

public toggleNav: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  public toggle(): void {
    this.toggleNav.next(!this.toggleNav.value);
  }

Ensuite, vous avez un composant à partir duquel vous souhaitez ouvrir ou fermer votre SideNav. Dans mon cas, j'ai créé le bouton dans le Navbar comme:

button *ngIf="this.loginService.tokenSubject.value"  mat-mini-fab color="warn" (click)="onToggle()"><mat-icon>menu</mat-icon></button>

Ensuite, dans le SideNavComponent que vous auriez créé pour SideNav, placez-le dans le mat-sidenav tag:

[opened]="this.sideNavService.toggleNav.value"

Bien sûr, j'ai injecté le NavService en tant que sideNavService dans le constructeur de ce composant.

0
Imran Faruqi