Home > Enterprise >  Responsive navbar with Angular material schematics
Responsive navbar with Angular material schematics

Time:05-12

Using https://material.angular.io/guide/schematics, it's straight forward to create a navigation system.

ng generate @angular/material:navigation <componenet-name>

Generates below template with required functionalities in component

<mat-sidenav-container >
  <mat-sidenav #drawer  fixedInViewport
      [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
      [mode]="(isHandset$ | async) ? 'over' : 'side'"
      [opened]="(isHandset$ | async) === false">
    <mat-toolbar>Menu</mat-toolbar>
    <mat-nav-list>
      <a mat-list-item href="#">Link 1</a>
      <a mat-list-item href="#">Link 2</a>
      <a mat-list-item href="#">Link 3</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <mat-toolbar color="primary">
      <button
        type="button"
        aria-label="Toggle sidenav"
        mat-icon-button
        (click)="drawer.toggle()"
        *ngIf="isHandset$ | async">
        <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>
      <span>thingschain-web</span>
    </mat-toolbar>
    <!-- Add Content Here -->
  </mat-sidenav-content>
</mat-sidenav-container>

It always keeps the sidebar open on desktop browsers. It also appropriately closes sidebar on mobile devices. So far this is exactly what I want. But on mobile browsers, I want the sidebar to close on click events on any of the mat-list-items.

Adding a click event like below in mat-nav-list closes the sidebar

    <mat-nav-list (click)="drawer.close()">
      <a mat-list-item href="#">Link 1</a>
      <a mat-list-item href="#">Link 2</a>
      <a mat-list-item href="#">Link 3</a>
    </mat-nav-list>

But I want it to close on mobile browsers only so tried:

(click)="(isHandset$ | async) ? drawer.close() : drawer.open()"

And getting below error

Parser Error: Cannot have a pipe in an action expression at column 15 in [(isHandset$ | async) ? drawer.close()] in /path/to/component/html/template

CodePudding user response:

You are on the right track. What I would do in this case is subscribe to the observable and keep track of the value in a variable that isn't observable. I try to keep things as observables if I can, but in this case, I would handle it this way.

constructor() {
    this.isHandset$.subscribe(isHandset => this.isHandset = isHandset)
}
(click)="isHandset ? drawer.close() : drawer.open()"
  • Related