Angular-открыть / закрыть sidenav из другого компонента

Я использую угловой (последняя версия) и угловые материал.

есть 3 компонента:

    .компонент, в котором есть кнопка управления для правого sidenav
  • справа-sidenav.компонент, в котором находится правая сторона-sidenav
  • sidenav.компонент (это главное меню слева), этот компонент вызывает заголовок.компонент, правой sidenav.компонент и содержание

впервые я работаю с Angular, скажите мне, пожалуйста, как открыть / закрыть sidenav из другого компонента (в моем случае кнопка находится в заголовке.деталь.)

попробовал следующий вариант (но получил ошибку: TypeError: this.RightSidenavComponent.rightSidenav является undefined):

заголовок.деталь.HTML-код

<button mat-button (click)="toggleRightSidenav()">Согласование до 16:00 сегодня</button>

заголовок.деталь.ТС

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.деталь.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.деталь.ТС

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;
	}
	
}

правой sidenav.деталь.HTML-код

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

правой sidenav.деталь.ТС

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() { }

}

неработающего пример с кодом stackblitz

2 ответов


у меня была такая же проблема с использованием. Я решил это так.

SidenavService

import { Injectable } from '@angular/core';
import { MatSidenav } from '@angular/material';

@Injectable()
export class SidenavService {
    private sidenav: MatSidenav;


    public setSidenav(sidenav: MatSidenav) {
        this.sidenav = sidenav;
    }

    public open() {
        return this.sidenav.open();
    }


    public close() {
        return this.sidenav.close();
    }

    public toggle(): void {
    this.sidenav.toggle();
   }

Компонент

constructor(
private sidenav: SidenavService) { }

toggleRightSidenav() {
   this.sidenav.toggle();
}

свяжите свой HTML-переключатель () на основе вашего требования.

приложение компонент.

@ViewChild('sidenav') public sidenav: MatSidenav;

constructor(private sidenavService: SidenavService) {
}

ngOnInit(): void {
  this.sidenavService.setSidenav(this.sidenav);
}

App Модуль

providers: [YourServices , SidenavService],

рабочий образец с кодом stackblitz


прежде всего, вам не нужно вызывать rightSideNav в компоненте sideNav. Кнопка переключения находится в компоненте заголовка. Таким образом, вы можете сделать это в своем компоненте header.

заголовок.деталь.ТС :

    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 {
        rightSideNav : boolean ;
        constructor(public RightSidenavComponent:RightSidenavComponent) {   }


        sideNavBtnToggle(){
        if(this.rightSideNav == false)
        {
               this.rightSideNav = true;
        }
        else{
               this.rightSideNav = false;
        } 
}
}

и в заголовок.деталь.HTML-код

ставим этот код :

<app-right-sidenav *ngIf="rightSideNav"></app-right-sidenav>

это сделает вашу работу легкой.