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

时间:2018-04-19 12:33:55

标签: angular breakpoints angular-cdk

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

breakpointObserver工作,除了我刚刚加载页面。 breakpointObserver仅在观察到更改后触发,但考虑到它是一个新的负载,尚未发生变化。这意味着尚未针对断点评估初始视口。我已尝试在BreakpointObserver.isMatched中使用单个OnInit,但这似乎没有任何效果。

我将BreakpointObserverBreakpointsMediaMatcher添加到共享服务中,我在其中订阅了所有需要" 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();
    }
}

1 个答案:

答案 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>

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