在将Angular BreakpointObserver
与Angular Material
结合使用时,我尝试使用Material Design规范断点(它们在Breakpoints
中定义,例如Breakpoints.LandscapePortrait
},Breakpoints.HandsetPortrait
)。
breakpointObserver工作,除了我刚刚加载页面。 breakpointObserver仅在观察到更改后触发,但考虑到它是一个新的负载,尚未发生变化。这意味着尚未针对断点评估初始视口。我已尝试在BreakpointObserver.isMatched
中使用单个OnInit
,但这似乎没有任何效果。
我将BreakpointObserver
,Breakpoints
和MediaMatcher
添加到共享服务中,我在其中订阅了所有需要" listen"到了断点。
我的问题是:如何确保在第一个视口更改之前评估断点(如果用户没有调整窗口/更改设备方向,可能根本不会发生这种情况)?
这是我shared.service.ts
的代码:
import {Component, OnDestroy, OnInit, Injectable,Input,Output,EventEmitter} from '@angular/core';
import {BreakpointObserver, Breakpoints, MediaMatcher} from '@angular/cdk/layout';
@Injectable()
export class SharedService implements OnDestroy, OnInit {
public isCollapsed = false;
public isOpen = false;
public isMobileView = false;
public isTabletView = false;
private breakpointObserver: BreakpointObserver;
@Output() mediaChange = new EventEmitter();
constructor(breakpointObserver: BreakpointObserver) {
this.breakpointObserver = breakpointObserver;
// check if the viewport matches Material Design-spec handset displays
this.breakpointObserver.observe([
Breakpoints.HandsetPortrait
]).subscribe(result => {
if (result.matches) {
this.isMobileView = true;
this.isTabletView = false;
this.isOpen = false;
this.isCollapsed = false;
}
else {
this.isMobileView = false;
this.isOpen = true;
this.isCollapsed = false;
}
this.mediaChanged();
});
// check if the viewport matches Material Design-spec tablet displays
this.breakpointObserver.observe([
Breakpoints.TabletPortrait
]).subscribe(result => {
if (result.matches) {
this.isTabletView = true;
this.isMobileView = false;
this.isOpen = true;
this.isCollapsed = true;
}
else {
if(!this.isMobileView){
this.isOpen = true;
}
this.isTabletView = false;
this.isCollapsed = false;
}
this.mediaChanged();
});
}
mediaChanged() {
this.mediaChange.emit({
"isMobileView" : this.isMobileView,
"isTabletView" : this.isTabletView,
"isCollapsed" : this.isCollapsed,
"isOpen" : this.isOpen
});
}
ngOnInit() {
// MY ATTEMPT
// Running the same checks as the observer, but this time on init(?)
// does not seem to take any effect
if(this.breakpointObserver.isMatched([
Breakpoints.HandsetPortrait
])){
this.isMobileView = true;
this.isTabletView = false;
this.isOpen = false;
this.isCollapsed = false;
}
if(this.breakpointObserver.isMatched([
Breakpoints.TabletPortrait
])){
this.isTabletView = true;
this.isMobileView = false;
this.isOpen = true;
this.isCollapsed = true;
}
this.mediaChanged();
}
}
答案 0 :(得分:0)
将本地变量设置为false并根据订阅中的值进行更改。
import { Component, OnInit } from '@angular/core';
import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-main-menu',
templateUrl: './main-menu.component.html',
styleUrls: ['./main-menu.component.css']
})
export class MainMenuComponent implements OnInit {
isHandset = false;
constructor(private breakpointObserver: BreakpointObserver, private route: ActivatedRoute) {}
ngOnInit() {
this.breakpointObserver.observe(Breakpoints.Handset)
.subscribe((state: BreakpointState) => {
if (state.matches) {
this.isHandset = true;
} else {
this.isHandset = false;
}
});
}
}
模板代码:
<mat-sidenav-container class="sidenav-container">
<mat-sidenav #drawer class="sidenav" fixedInViewport
[attr.role]="isHandset ? 'dialog' : 'navigation'"
[mode]="isHandset ? 'over' : 'side'"
[opened]="isHandset === 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">
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
</button>
<span>timplaw-dotcom</span>
</mat-toolbar>
<!-- Add Content Here -->
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>