Reputation: 1967
This is the exact same code from Angular material website showing how to create different sidenav
for mobile and desktop.
<div class="example-container" [class.example-is-mobile]="mobileQuery.matches" *ngIf="shouldRun">
<mat-toolbar color="primary" class="example-toolbar">
<button mat-icon-button (click)="snav.toggle()"><mat-icon>menu</mat-icon></button>
<h1 class="example-app-name">Responsive App</h1>
</mat-toolbar>
<mat-sidenav-container class="example-sidenav-container"
[style.marginTop.px]="mobileQuery.matches ? 56 : 0">
<mat-sidenav #snav [mode]="mobileQuery.matches ? 'over' : 'side'"
[fixedInViewport]="mobileQuery.matches" fixedTopGap="56">
<mat-nav-list>
<a mat-list-item routerLink="." *ngFor="let nav of fillerNav">{{nav}}</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<p *ngFor="let content of fillerContent">{{content}}</p>
</mat-sidenav-content>
</mat-sidenav-container>
</div>
<div *ngIf="!shouldRun">Please open on Stackblitz to see result</div>
I want the menu button only appear when it is mobile. I add *ngIf="mobileQuery.matches"
to it.
Change the 3rd line to:
<button mat-icon-button *ngIf="mobileQuery.matches" (click)="snav.toggle()"><mat-icon>menu</mat-icon></button>
Strangely, if you resize the window to make the button disappear then resize it to make the button appear again, the button won't work anymore. The sidenav
will not show when you click it. Only when you resize the window again, the menu will suddenly appear.
Upvotes: 2
Views: 2950
Reputation: 53
I had the same issue. After removing changeDetectorRef.detectChanges() the issue was gone.
Upvotes: 0
Reputation: 689
Since your main goal is to show/hide the menu button, I think you only need the following code into the constructor:
constructor(media: MediaMatcher) {
this.mobileQuery = media.matchMedia('(max-width: 600px)');
}
Everything works fine after applying that change. Take a look at this stackblitz.
Let me know if that helps!
Upvotes: 2
Reputation: 2273
This is a strange one. It actually is a problem with change detection. If you manually trigger change detection after toggling the sidebar, everything works fine. Consider the following:
<!-- On click, call our toggle function which will toggle the side-nav and
trigger change detection -->
<button mat-icon-button *ngIf="mobileQuery.matches" (click)="toggle(snav)"><mat-icon>menu</mat-icon></button>
And our toggle
function:
toggle(sidenav: any) {
sidenav.toggle();
this.changeDetectorRef.detectChanges();
}
Everything works as expected. Additionally, if you just show/hide the button (don't remove it from the DOM), everything works as expected:
<!-- As long as you only show/hide the button, everything works as expected -->
<div [hidden]="!mobileQuery.matches">
<button mat-icon-button (click)="snav.toggle()"><mat-icon>menu</mat-icon></button>
</div>
I have created a stackblitz that shows these examples working. This is really strange and I think you may have discovered a bug in Angular Material. Let me know if you are going to submit a bug request on the repo; if not, I will.
Upvotes: 3
Reputation: 1199
The click event works fine (you can add some logs to check it), it's actually the media query on the mat-sidenav tag (line 9) that breaks the snav.toggle()
Upvotes: -1