Angular Material:BreakpointObserver 无法从负载中获得?

Jer*_*oen 6 breakpoints angular angular-cdk

在将 AngularBreakpointObserver与 结合使用时Angular Material,我尝试使用 Material Design 规范的断点(Breakpoints例如Breakpoints.LandscapePortrait,它们在 中定义Breakpoints.HandsetPortrait)。

breakpointObserver 工作,除了当我刚加载页面时。breakpointObserver 仅观察到更改才会触发,但考虑到它是新加载,目前还没有更改。这意味着尚未针对断点评估初始视口。我试过使用单个BreakpointObserver.isMatchedin OnInit,但这似乎没有任何效果。

我列入BreakpointObserverBreakpointsMediaMatcher到共享服务,这是我在所有认购组件需要“听”到断点。

我的问题是:如何确保在第一次视口更改之前评估断点(如果用户不调整窗口大小/更改设备方向,这可能根本不会发生)?

这是我的代码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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Whe*_*-pi 4

将局部变量设置为 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;
        }
      });
  }

}
Run Code Online (Sandbox Code Playgroud)

模板代码:

<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>
Run Code Online (Sandbox Code Playgroud)

参考:https://alligator.io/angular/breakpoints-angular-cdk/