Material2: Show / hide md-sidenav depending on media

I would like to open md-sidenav on the big screen and close it on the mobile device. What would be the correct way to do this in my application?

Is it possible to request media inside the angular2 component?

+4
source share
5 answers

Inside the component class, I defined a link to sidenav and listen for window resizing events. Depending on window.innerWith you can build your own logic.

  @ViewChild('sidenav') sidenav: MdSidenav

  @HostListener('window:resize', ['$event'])
  onResize(event) {
    this.configureSideNav()
  }

  configureSideNav() {
    this.smallScreen = window.innerWidth < 501 ? true : false
    if (!this.smallScreen) {
      this.sidenav.mode = "side"
      this.sidenav.opened = true
    } else {
      this.sidenav.mode = 'over'
      this.sidenav.opened = false
    }
  }
+7
source

We have a toolbar component that is the layout container for the entire application.

dashboard.html:

<md-sidenav-layout class="sidenav-layout">

  <bv-toolbar (toggleSidenav)="start.toggle()" [screenWidth]="screenWidth"></bv-toolbar>
  <md-sidenav #start [opened]="screenWidth > 1000" [mode]="(screenWidth > 1000) ? 'side' : 'start'">
    <bv-sidenav-content  [user]="user$ | async" [screenWidth]="screenWidth" (navClose)="start.toggle()"></bv-sidenav-content>
  </md-sidenav>

  <div class="sidenav-content"></div>
</md-sidenav-layout>

, ( sidenav) [screenWidth]="screenWidth".

dashboard.ts:

...
export class DashboardComponent {
  screenWidth: number;
...
constructor (private cdr: ChangeDetectorRef, private store: Store<fromRoot.State> ) {

  var that = this;
  // set screenWidth on page load
  that.screenWidth = window.innerWidth;
  window.onresize = () => {
    // set screenWidth on screen size change
    that.screenWidth = window.innerWidth;
    that.cdr.detectChanges();
  }
}

, screenWidth , script @Input(), .

toolbar.ts:

...
export class ToolbarComponent {
  @Output() toggleSidenav = new EventEmitter();
  @Input() screenWidth : number;
}

screenWidth, , ( .

toolbar.html:

<md-toolbar color="primary">
  <button md-icon-button
          (click)="toggleSidenav.emit()"
          [ngClass]="{'h-hide': screenWidth > 1000}">
      <md-icon>menu</md-icon>
  </button>
</md-toolbar>
+1

: rxjs/behaviorsubject.

BehaviorSubject.window. , sidenav "side" "over".

windows.service.ts:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class WindowService {
    public window = new BehaviorSubject(null);

    public width: Observable<number>;

    constructor() {
        let windowSize = new BehaviorSubject(getWindowSize());

        this.width = (windowSize.pluck('width') as Observable<number>).distinctUntilChanged();

        Observable.fromEvent(window, 'resize')
            .map(getWindowSize)
            .subscribe(windowSize);
    }


}

function getWindowSize() {
    return {
        width: window.innerWidth
    };
}

component.ts:

ngOnInit() {
    // Change sideNav mode between over and side depending on size of window
    this.windowService.width.subscribe((width) => {
      if (width) {
        console.log(width);
        if (width < 600) {
          this.sideNavMode = "over"
        } else {
          this.sideNavMode = "side"
        }
      }
    });
}
+1

Angular: https://github.com/angular/flex-layout/wiki/ObservableMedia

Angular Flex Layout, mediaQuery . , resize .

, MediaChange (lg, md, xs ..), , .

-.

0

. , , @AndyGrey . , -.

sidenav-layout.component.ts

    import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
    import { ObservableMedia, MediaChange } from '@angular/flex-layout';
    import { MdSidenav } from '@angular/material';
    import { Subscription } from 'rxjs/Subscription';

    @Component({
      selector: 'sidenav-layout',
      templateUrl: './sidenav-layout.component.html',
      styleUrls: [ './sidenav-layout.component.scss' ]
    })

    export class SidenavLayoutComponent implements OnInit, OnDestroy {

      @ViewChild('sidenav') sidenav: MdSidenav;

      private _mediaSubscription: Subscription;
      sidenavOpen = true;
      isMobile = false;

      constructor(private media: ObservableMedia) {}

      ngOnInit() {
        this._mediaSubscription = this.media.asObservable().subscribe((change: 
     MediaChange) => {
      this.isMobile = (change.mqAlias === 'xs') || (change.mqAlias === 'sm');
      this.sidenavOpen = !this.isMobile;
    });
  }

  onLinkClick() {
    if (this.isMobile) {
      this.sidenav.toggle();
    }
  }

  ngOnDestroy() {
    this._mediaSubscription.unsubscribe();
  }
}

sidenav-layout.component.html

 <md-sidenav #sidenav mode="side" opened={{sidenavOpen}}>

onLinkClick() . , , sidenav ().

mediaSubscription Observable:)

0
source

Source: https://habr.com/ru/post/1659272/


All Articles