简体   繁体   中英

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

how do I toggle the sidenav from another component?

When the button/trigger is in the same.html file as the sidenav, it work just fine, but if I generate a new component, in my case I named them "sidebar-left" and "topbar," it don't work.

What I did is I generated components to separate them. I put the sidenav in the "sidebar-left" component and the button/trigger in "topbar" component.

sidebar-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>

I would like to be able to trigger the sidenav no matter where I trigger it inside the application.

And when I do hit the toggle button, I'm having this error:

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

There are three posible ways to communicate between components. The error you are getting is because there is not sidevav property in your component and no toggle function is declared on an undefined member.

There are specific ways you can communicate between components.

Use the native event driven communication.

Parent to child through input (value), child to parent through output (event).

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

  constructor() { }

  emit() {
      this.toggle.emit(null);
  }
  • In your TopbarComponent you add the above code.
  • In your AppComponent you bind to the toggle

and in the ts file you create the toggle function

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

Then you pass the first selected value to your components and hide unhide accordingly.

This is the official way. Check this solution working on stackblitz here

Use an event service

You can create an event service from which you can raise events and the toggle master can subscribe to them and toggle application wide. check for example here

Use a libary to share state via stores

Check documentation here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM