如何在 Angular Material 中将 sidenav(mat-drawer)状态保存到本地存储?
How to save sidenav (mat-drawer) state to localstorage in Angular Material?
我在 Angular Material 中遇到垫子抽屉的问题。我想将我的状态保存到本地存储,但 mat-drawer 总是打开的。
当没有文字的垫子图标时,Sidenav 有展开部分和关闭展开部分。当您单击底部按钮隐藏时,sidenav 关闭但刷新页面后 Sidenav 再次展开(但在 localstorage 中关闭)。
看起来像这样:
Opened expanded mat drawer
Closed mat drawer
Sidenav is open but in local storage is closed
你知道怎么解决这个问题吗?谢谢!
源代码:
app.component.html
<mat-drawer-container class="content-container" autosize >
<mat-drawer
mode="side"
class="sidenav"
disableClose="true"
opened="true">
<div class="sidenav-container">
<mat-nav-list>
<a class="nav-item nav-link" mat-list-item routerLink="/private/dashboard" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
<mat-icon style="padding-right:5px;" matTooltipPosition="right" [matTooltipDisabled]="disabledTooltip">dashboard</mat-icon>
<span *ngIf="isExpanded">Dashboard</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/companies" routerLinkActive="active">
<mat-icon style="padding-right:5px;">stars</mat-icon>
<span *ngIf="isExpanded">Subjects</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/users" routerLinkActive="active">
<mat-icon style="padding-right:5px;">group</mat-icon>
<span *ngIf="isExpanded">Users</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/api-customers" routerLinkActive="active">
<mat-icon style="padding-right:5px;">beenhere</mat-icon>
<span *ngIf="isExpanded">Clients</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/applications" routerLinkActive="active">
<mat-icon style="padding-right:5px;">apps</mat-icon>
<span *ngIf="isExpanded">Apps</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/calendar" routerLinkActive="active">
<mat-icon style="padding-right:5px;">calendar_today</mat-icon>
<span *ngIf="isExpanded">Calendar</span>
</a>
</mat-nav-list>
<div class="sidenav-bottom">
<mat-nav-list>
<a class="nav-item nav-link" mat-list-item (click)="onSidenavToggle()">
<mat-icon *ngIf="isExpanded">arrow_back_ios</mat-icon>
<mat-icon *ngIf="!isExpanded">arrow_forward_ios</mat-icon>
<span *ngIf="isExpanded">Hide</span>
</a>
</mat-nav-list>
</div>
</mat-drawer>
<mat-drawer-content>
Page content
</mat-drawer-content>
</mat-drawer-container>
app.component.ts
import {Component, HostListener, Inject, OnInit} from '@angular/core';
import { Router } from '@angular/router';
import {Subject} from 'rxjs';
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
isExpanded = true;
constructor(
private sidenavService: SidebarService) {
this.sidenavService.setHideSidebar(this.sidenavService.isHideSidebar());
}
onSidenavToggle() {
this.isExpanded = !this.isExpanded;
this.sidenavService.setHideSidebar(!this.sidenavService.isHideSidebar());
this.sidenavService.sideBarState$.next(this.isExpanded);
}}
sidebar.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class SidebarService {
public sideBarState$: Subject<boolean> = new Subject<boolean>();
constructor() {
const initialValue = localStorage.getItem('isExpanded');
this.sideBarState$.next(initialValue === 'close');
}
getHideSidebar(): Subject<boolean> {
return this.sideBarState$;
}
setHideSidebar(newValue: boolean): void {
localStorage.setItem('isExpanded', newValue ? 'close' : 'open');
this.sideBarState$.next(newValue);
}
isHideSidebar(): boolean {
return localStorage.getItem('isExpanded') === 'close';
}
}
原来问题出在组件中的 isExpanded
上。该值被硬编码为 true
,与服务(或存储在 LOCALSTORAGE 中的值)无关。
其他一些建议是单独使用 Subject
值作为 isExpanded
应该是什么的真正来源(使用 EMIT 值,不要自己设置)。如果将 isExpanded
存储为 true 或 false,而不是 open
或 close
,这也会更有意义。变量名称表明该值为真或假。
import {Component, HostListener, Inject, OnInit} from '@angular/core';
import { Router } from '@angular/router';
import {Subject} from 'rxjs';
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
isExpanded;
constructor(
private sidenavService: SidebarService) {
isExpanded = !this.sidenavService.isHideSidebar();
}
onSidenavToggle() {
this.isExpanded = !this.isExpanded;
this.sidenavService.setHideSidebar(!this.sidenavService.isHideSidebar());
this.sidenavService.sideBarState$.next(this.isExpanded);
}}
我在 Angular Material 中遇到垫子抽屉的问题。我想将我的状态保存到本地存储,但 mat-drawer 总是打开的。
当没有文字的垫子图标时,Sidenav 有展开部分和关闭展开部分。当您单击底部按钮隐藏时,sidenav 关闭但刷新页面后 Sidenav 再次展开(但在 localstorage 中关闭)。
看起来像这样:
Opened expanded mat drawer
Closed mat drawer
Sidenav is open but in local storage is closed
你知道怎么解决这个问题吗?谢谢!
源代码:
app.component.html
<mat-drawer-container class="content-container" autosize >
<mat-drawer
mode="side"
class="sidenav"
disableClose="true"
opened="true">
<div class="sidenav-container">
<mat-nav-list>
<a class="nav-item nav-link" mat-list-item routerLink="/private/dashboard" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
<mat-icon style="padding-right:5px;" matTooltipPosition="right" [matTooltipDisabled]="disabledTooltip">dashboard</mat-icon>
<span *ngIf="isExpanded">Dashboard</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/companies" routerLinkActive="active">
<mat-icon style="padding-right:5px;">stars</mat-icon>
<span *ngIf="isExpanded">Subjects</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/users" routerLinkActive="active">
<mat-icon style="padding-right:5px;">group</mat-icon>
<span *ngIf="isExpanded">Users</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/api-customers" routerLinkActive="active">
<mat-icon style="padding-right:5px;">beenhere</mat-icon>
<span *ngIf="isExpanded">Clients</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/applications" routerLinkActive="active">
<mat-icon style="padding-right:5px;">apps</mat-icon>
<span *ngIf="isExpanded">Apps</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/calendar" routerLinkActive="active">
<mat-icon style="padding-right:5px;">calendar_today</mat-icon>
<span *ngIf="isExpanded">Calendar</span>
</a>
</mat-nav-list>
<div class="sidenav-bottom">
<mat-nav-list>
<a class="nav-item nav-link" mat-list-item (click)="onSidenavToggle()">
<mat-icon *ngIf="isExpanded">arrow_back_ios</mat-icon>
<mat-icon *ngIf="!isExpanded">arrow_forward_ios</mat-icon>
<span *ngIf="isExpanded">Hide</span>
</a>
</mat-nav-list>
</div>
</mat-drawer>
<mat-drawer-content>
Page content
</mat-drawer-content>
</mat-drawer-container>
app.component.ts
import {Component, HostListener, Inject, OnInit} from '@angular/core';
import { Router } from '@angular/router';
import {Subject} from 'rxjs';
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
isExpanded = true;
constructor(
private sidenavService: SidebarService) {
this.sidenavService.setHideSidebar(this.sidenavService.isHideSidebar());
}
onSidenavToggle() {
this.isExpanded = !this.isExpanded;
this.sidenavService.setHideSidebar(!this.sidenavService.isHideSidebar());
this.sidenavService.sideBarState$.next(this.isExpanded);
}}
sidebar.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class SidebarService {
public sideBarState$: Subject<boolean> = new Subject<boolean>();
constructor() {
const initialValue = localStorage.getItem('isExpanded');
this.sideBarState$.next(initialValue === 'close');
}
getHideSidebar(): Subject<boolean> {
return this.sideBarState$;
}
setHideSidebar(newValue: boolean): void {
localStorage.setItem('isExpanded', newValue ? 'close' : 'open');
this.sideBarState$.next(newValue);
}
isHideSidebar(): boolean {
return localStorage.getItem('isExpanded') === 'close';
}
}
原来问题出在组件中的 isExpanded
上。该值被硬编码为 true
,与服务(或存储在 LOCALSTORAGE 中的值)无关。
其他一些建议是单独使用 Subject
值作为 isExpanded
应该是什么的真正来源(使用 EMIT 值,不要自己设置)。如果将 isExpanded
存储为 true 或 false,而不是 open
或 close
,这也会更有意义。变量名称表明该值为真或假。
import {Component, HostListener, Inject, OnInit} from '@angular/core';
import { Router } from '@angular/router';
import {Subject} from 'rxjs';
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
isExpanded;
constructor(
private sidenavService: SidebarService) {
isExpanded = !this.sidenavService.isHideSidebar();
}
onSidenavToggle() {
this.isExpanded = !this.isExpanded;
this.sidenavService.setHideSidebar(!this.sidenavService.isHideSidebar());
this.sidenavService.sideBarState$.next(this.isExpanded);
}}