Peter Nixey
Peter Nixey

Reputation: 16565

Why won't mat-drawer respond to `.toggle` when it's called from outside its own component?

I'm using mat-drawer to add sidenav to a page. I'm putting the drawer into a side-nav-container component that will be common to all pages so that each page can have the following structure:

<!-- a page in my app -->
<app-side-nav-container #container>

  <!-- Button to trigger side-nav to open or close -->
  <button type="button" mat-button (click)="container.tryToggle()">
    Toggle nav (from an element on the page)
  </button>

  Content in the rest of the page

</app-side-nav-container>

In the code above I'm triggering the toggle behaviour by calling a .tryToggle() method which exists on the side-nav-container element. I've used the #container notation to create a reference to the container component. This is that container component:

export class SideNavContainerComponent {

  @ViewChild('drawer')
  public drawer?: MatDrawer

  public tryToggle() :void {
    console.log('Toggling. drawer.opened=' + this.drawer?.opened)
    this.drawer?.toggle()
  }
}

.tryToggle() is accessible from the projected content but won't trigger the drawer

When I click "Toggle nav" in the projected content, the console.log call works as expected and prints the value of this.drawer?.opened. This value alternates between true and false.

enter image description here

However the drawer doesn't work. It won't open or close. It's very peculiar. It's not that the drawer is out of scope - it's in scope and I can print it into the console. It just doesn't open or close.

.tryToggle works when called by an element inside the container component

If I call exactly the same method but triggered by button inside the the parent component then it works.

// side-nav-container.html
<mat-drawer-container class="example-container" autosize>
  
  <mat-drawer #drawer mode="side">
    <p>Sidenav content </p>
  </mat-drawer>

  <div class="body-of-page">
    <ng-content></ng-content>
  </div>

  <!-- additional button to test behaviour... --> 
  <button type="button" mat-button (click)="tryToggle()">
    Toggle sidenav (this works)
  </button>
</mat-drawer-container>

What am I missing?

Upvotes: 1

Views: 1465

Answers (1)

Matthieu Riegler
Matthieu Riegler

Reputation: 55699

Had a similar problem because of ChangeDetectionStrategy.OnPush.

I had to do an explicit call to markForCheck on the ChangeDetectorRef.

Upvotes: 1

Related Questions