web-dev-qa-db-ja.com

別のコンポーネントからのサイドナビを開く/閉じる

私はangular(最新バージョン)とangularマテリアルを使用しています。

3つのコンポーネントがあります。

  • header.component、right-sidenavのコントロールボタンがあります
  • rigth-sidenav.component、右側はsidenav
  • sidenav.component(これは左側のメインメニューです)、このコンポーネントはheader.component、right-sidenav.componentおよびcontentを呼び出します

別のコンポーネントからsidenavを開く/閉じる方法は? (私の場合、ボタンはheader.componentにあります)。

次のオプションを試しました(ただし、エラーが発生しました: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() { }

}

コードstackblitzを使用した非稼働サンプル

30
Denis

Angular 9+で作業している場合は、次のように_static: true_に_@ViewChild_のパラメータを追加することを忘れないでください。

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

私のコードがAngular 9ここで動作しているのを見ることができます:

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

1
amolinaoOT

Eldhoの答えに追加するために、アニメーションを無効にして真の非表示効果を得ることができます。

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

上記の人々はすでに答えましたが、私が自分で解決した方が私の解決策はもっと簡単だと思います。

両方のコンポーネントをサポートするには、中間にサービスが必要です。

そのようなサービスがNavServiceであるとしましょう。以下のコードはNavServiceに入ります:

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

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

次に、SideNavを開いたり閉じたりする場所のコンポーネントがあります。私の場合、Navbarに次のようにボタンを作成しました。

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

次に、SideNavComponent用に作成したSideNavに、これをmat-sidenav 鬼ごっこ:

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

もちろん、このコンポーネントのコンストラクターにNavServiceをsideNavServiceとして挿入しました。

0
Imran Faruqi