首页 > 解决方案 > 我做的事情不是让sidenav模式根据屏幕宽度动态切换吗?

问题描述

我正在尝试在具有 2 种状态的 Angular Material 中制作 sidenav,用于移动模式(平板电脑、手机和小窗口)和桌面(显示器上的典型窗口大小)。如果用户之前打开了sidenav(使用localStorage),我也想保存在localStorage中,所以我订阅了BreakpointObserver,如果宽度小于1024px,它将sidenav模式更改为“悬停”,否则它会在localStorage中查找用户选项“sideNav” false 不会打开,如果是 true 则默认打开。如果您调整窗口大小,它会重复整个过程。我开始认为从性能和代码清除的角度来看,我正在写一些愚蠢的东西。

Sidenav服务:

import { Injectable } from '@angular/core';
import { MatDrawer, MatDrawerMode } from '@angular/material/sidenav';
import { BreakpointObserver } from '@angular/cdk/layout';
import { LocalStorageService } from '../local-storage/local-storage.service';

@Injectable({
  providedIn: 'root',
})
export class SideNavService {
  public drawer: MatDrawer;
  hasBackdrop: boolean = null;
  mode: MatDrawerMode = this.breakpointObserver
    .isMatched('(min-width: 1024px)') ? 'side' : 'over';
  isSidenavOpened: boolean = this.mode === 'side' ?
    this.localStorageService.isSidenavOpened.value : false;

  constructor(
    private breakpointObserver: BreakpointObserver,
    private localStorageService: LocalStorageService
  ) {
    this.breakpointObserver.observe('(min-width: 1024px)')
      .subscribe(result => {
        const res = result.matches ? 'side' : 'over';
        this.mode = res;
        if (res === 'side') {
          this.isSidenavOpened = this.localStorageService.isSidenavOpened.value;
        } else {
          this.isSidenavOpened = false;
        }
      });
  }

  public toggleSideNav(): void {
    if (this.mode === 'side') {
      this.localStorageService.isSidenavOpened.value =
        !this.localStorageService.isSidenavOpened.value;
    }
    this.drawer.toggle().then();
  }
}

app.component.html:

<span [ngClass]="themeService.selectedTheme">
  <div class="mat-app-background without-header">
    <app-header [title]="title"></app-header>

    <mat-drawer-container class="mat-drawer-container" [hasBackdrop]='sideNavService.hasBackdrop'>
      <mat-drawer #drawer [mode]="sideNavService.mode" [opened]='sideNavService.isSidenavOpened'>
        <app-sidebar></app-sidebar>
      </mat-drawer>

      <mat-drawer-content>
        <div class="d-flex flex-grow-1 flex-column
             justify-content-between min-height-100">
          <div>
            <router-outlet></router-outlet>
          </div>
          <app-footer [title]="title"></app-footer>
        </div>
      </mat-drawer-content>
    </mat-drawer-container>
  </div>
</span>

标签: htmlangulartypescriptangular-material

解决方案


推荐阅读