从另一个组件打开/关闭 sidenav [英] Open/Close sidenav from another component

查看:32
本文介绍了从另一个组件打开/关闭 sidenav的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用角(最新版本)和角材料.

有3个组成部分:

  • header.component,里面有一个右侧导航的控制按钮
  • rigth-sidenav.component,其中是右侧导航
  • sidenav.component(这是左边的主菜单),这个组件调用了header.component、right-sidenav.component和content

如何从另一个组件打开/关闭 sidenav?(在我的例子中,按钮在 header.component 中).

尝试了以下选项(但得到错误:TypeError: this.RightSidenavComponent.rightSidenav is undefined):

header.component.html

header.component.ts

import { Component } from '@angular/core';从'../right-sidenav/right-sidenav.component'导入{RightSidenavComponent};@成分({选择器:'应用程序头',templateUrl: './header.component.html',styleUrls: ['./header.component.scss']})导出类 HeaderComponent {构造函数(公共RightSidenavComponent:RightSidenavComponent){}切换RightSidenav() {this.RightSidenavComponent.rightSidenav.toggle();}}

sidenav.component.html

<mat-sidenav #sidenav mode="side" opens="true" class="sidenav"[fixedInViewport]="true">Sidenav </mat-sidenav><mat-sidenav-content><app-header></app-header><路由器插座></路由器插座><app-right-sidenav #rSidenav></app-right-sidenav></mat-sidenav-content></mat-sidenav-container>

sidenav.component.ts

import { Component, Directive, ViewChild } from '@angular/core';从'../right-sidenav/right-sidenav.component'导入{RightSidenavComponent};@成分({选择器:'app-sidenav',templateUrl: './sidenav.component.html',styleUrls: ['./sidenav.component.scss']})导出类 SidenavComponent {@ViewChild('rSidenav') 公共 rSidenav;构造函数(公共 RightSidenavComponent:RightSidenavComponent){this.RightSidenavComponent.rightSidenav = this.rSidenav;}}

right-sidenav.component.html

<mat-sidenav #rightSidenav mode="side" opens="true" class="rightSidenav"[fixedInViewport]="true" [fixedTopGap]="250">西德纳夫</mat-sidenav>

right-sidenav.component.ts

import { Component, Injectable } from '@angular/core';@成分({选择器:'app-right-sidenav',templateUrl: './right-sidenav.component.html',styleUrls: ['./right-sidenav.component.scss']})@Injectable()导出类 RightSidenavComponent {公共权利Sidenav:任何;构造函数(){}}

非工作示例代码 stackblitz

解决方案

我在使用时遇到了同样的问题.我是这样解决的.

SidenavService

import { Injectable } from '@angular/core';从'@angular/material' 导入 { MatSidenav };@Injectable()导出类 SidenavService {私人sidenav:MatSidenav;公共 setSidenav(sidenav: MatSidenav) {this.sidenav = sidenav;}公共开放(){返回 this.sidenav.open();}公共关闭(){返回 this.sidenav.close();}公共切换():无效{this.sidenav.toggle();}

您的组件

构造函数(私人 sidenav: SidenavService) { }切换RightSidenav() {this.sidenav.toggle();}

<块引用>

根据您的要求绑定您的 html toggle().

应用组件.

@ViewChild('sidenav') public sidenav: MatSidenav;构造函数(私有 sidenavService: SidenavService){}ngAfterViewInit(): 无效 {this.sidenavService.setSidenav(this.sidenav);}

应用模块

providers: [YourServices , SidenavService],

代码 stackblitz 的工作示例

Angular 9+ 更新

根据 SO 上的这个答案,无法再通过 @angular/material 导入组件code>.使用单独的辅助入口点,例如 @angular/material/button." 因此,请确保像这样导入 MatSidenav:

import { MatSidenav } from '@angular/material/sidenav';

I use angular (latest version) and angular material.

There are 3 components:

  • header.component, in which there is a control button for right-sidenav
  • rigth-sidenav.component, in which is the right-sidenav
  • sidenav.component (this is the left main menu), this component calls header.component, right-sidenav.component and content

How to open / close sidenav from another component ? (in my case, the button is in header.component).

Tried the following option (but got the error: TypeError: this.RightSidenavComponent.rightSidenav is undefined):

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

}

Non-working sample with code stackblitz

解决方案

I had the same problem using. I resolved it like this.

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

Your Component

constructor(
private sidenav: SidenavService) { }

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

Bind your html toggle() based on your requirement.

App component.

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

constructor(private sidenavService: SidenavService) {
}

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

App Module

providers: [YourServices , SidenavService],

Working sample with code stackblitz

Angular 9+ Update

Per this answer on SO, "Components can no longer be imported through @angular/material. Use the individual secondary entry-points, such as @angular/material/button." As such, make sure to import MatSidenav like so:

import { MatSidenav } from '@angular/material/sidenav';

这篇关于从另一个组件打开/关闭 sidenav的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆