angular - 如何在 Angular 8 中制作相同的材质 sidenav 行为?
问题描述
当我使用sidenav组件加载页面时,左侧的菜单已关闭。如何使菜单默认打开,只有在减小窗口宽度后,才出现汉堡按钮,菜单本身折叠?我想做同样的事情https://material.angular.io/components/categories
我使用该命令创建新组件:
ng generate @angular/material:nav <component-name>
(https://material.angular.io/guide/schematics)
导航.component.html
<mat-sidenav-container class="sidenav-container">
<mat-sidenav #drawer class="sidenav" 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="/about">About</a>
<a mat-list-item href="/contact">Contact</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>NavApp</span>
</mat-toolbar>
<router-outlet></router-outlet>
<!-- Add Content Here -->
</mat-sidenav-content>
</mat-sidenav-container>
导航.component.ts
import { Component } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Observable } from 'rxjs';
import { map, share } from 'rxjs/operators';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss']
})
export class NavigationComponent {
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
.pipe(
map(result => result.matches),
share()
);
constructor(private breakpointObserver: BreakpointObserver) {}
}
当我尝试更改 [opened]="true" 左侧菜单已打开,但 this.breakpointObserver.observe(Breakpoints.Handset) 没有事件绑定并且如果我调整窗口左侧菜单未关闭
解决方案
我相信您遇到的问题是,在您的组件中,您使用运算符在 HTML 模板中的四个订阅者(异步管道)之间share()
共享 observable 。this.breakpointObserver.observe()
这意味着这个 observable 将在它第一次被订阅(在<mat-sidenav>
元素中)时发出;此发射将被共享,但由于您的<button>
元素尚未创建,发射太早并且<button>
永远不会收到它。这意味着*ngIf
on 按钮将在第一次加载时评估为 false,即使isHandset$
实际上已经发出 true,因此您不会在移动视图上看到菜单按钮。
为了解决这个问题,您可以使用shareReplay()
运算符而不是share()
,它将重播来自this.breakpointObserver.observe()
所有新订阅者(例如 中的订阅者<button>
)的发射,即使它们是在发射之后创建的。
导航.component.ts
import { Component } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Observable } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss']
})
export class NavigationComponent {
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
.pipe(
map(result => result.matches),
shareReplay(1),
);
constructor(private breakpointObserver: BreakpointObserver) { }
}
推荐阅读
- python - 为什么使用 turicreate 和 export_coreml 到 .mlmodel 文件它是一个文件夹
- excel - Excel 宏 - 重复宏代码但应用于不同的列
- c# - protobuf-net 版本 2.X 到 3.X 迁移
- docker - 如何在带有凭据的 docker build 映像中使用 gcloud 命令
- docker - SSH 代理转发到 docker-compose 文件中的 docker 容器
- javascript - 如何在其他文件中调用函数的getter
- python - Python如何使用for循环对齐文本?
- python - 如何在 Python 中生成具有 4 位字符串和 4 位数字的随机码?
- php - rest api codeigniter 结果缺失列
- python - 考虑每个计数重新计算平均值