Angular Material: 当触发器在不同的组件中时如何切换 sidenav

Angular Material: How to toggle sidenav when the trigger is in a different component

如何从另一个组件切换 sidenav?

当 button/trigger 与 sidenav 在同一个 .html 文件中时,它工作得很好,但如果我生成一个新组件,在我的例子中我将它们命名为 "sidebar-left" 和 "topbar," 它不起作用。

我所做的是生成组件来将它们分开。我将 sidenav 放在 "sidebar-left" 组件中,将 button/trigger 放在 "topbar" 组件中。

边栏-left.component.html

<mat-sidenav-container>

    <mat-sidenav #sidenav mode="side" [(opened)]="opened" opened>
        <h3>Sidenav</h3>
    </mat-sidenav>

    <mat-sidenav-content>
        <app-dashboard></app-dashboard>
    </mat-sidenav-content>

</mat-sidenav-container>

topbar.component.html

<mat-toolbar>
    <button (click)="sidenav.toggle()" mat-raised-button>Toggle Sidenav</button>
</mat-toolbar>

无论我在应用程序中的什么地方触发 sidenav,我都希望能够触发它。

当我按下切换按钮时,我遇到了这个错误:

TopbarComponent.html:1 ERROR TypeError: Cannot read property 'toggle' of undefined
    at Object.eval [as handleEvent] (TopbarComponent.html:2)
    at handleEvent (core.js:43993)
    at callWithDebugContext (core.js:45632)
    at Object.debugHandleEvent [as handleEvent] (core.js:45247)
    at dispatchEvent (core.js:29804)
    at core.js:42925
    at HTMLButtonElement.<anonymous> (platform-browser.js:2668)
    at ZoneDelegate.invokeTask (zone-evergreen.js:391)
    at Object.onInvokeTask (core.js:39680)
    at ZoneDelegate.invokeTask (zone-evergreen.js:390)

Here is my not-working StackBlitz code

组件之间可以通过三种可能的方式进行通信。你得到的错误是因为你的组件中没有 sidevav 属性 并且没有在未定义的成员上声明切换函数。

您可以通过特定方式在组件之间进行通信。

使用本机事件驱动通信。

Parent 到 child 通过输入(值),child 到 parent 通过输出(事件)。

  //this is how to create an event emitter
  @Output() toggle: EventEmitter<any> = new EventEmitter();

  constructor() { }

  emit() {
      this.toggle.emit(null);
  }
  • 在您的 TopbarComponent 中添加以上代码。
  • 在您的 AppComponent 中,您绑定到开关

并在 ts 文件中创建切换函数

toggle() {
     this.firstSelected = !this.firstSelected;
}

然后将第一个选定的值传递给组件并相应地隐藏取消隐藏。

这是官方的方式。检查此解决方案是否适用于 stackblitz here

使用事件服务

您可以创建一个事件服务,您可以从中引发事件,切换大师可以订阅它们并在应用程序范围内切换。例如检查

使用库通过存储共享状态

检查文件 here