web-dev-qa-db-fra.com

Angular 5 Liste de matrices de grille sensible

j'ai créé une liste de grille avec la colonne 6 et je veux être un titre de grille prendre 100% de largeur sur les appareils à petit écran. Maintenant, il crée également 6 colonnes sur de petits écrans

Attendu: un titre de grille occupe 100% de l'espace sur un appareil mobile uniquement.

28
Somnath Swami

Vous devez définir l'attribut cols de mat-grid-list de manière dynamique en fonction de la largeur de l'écran. Vous devez décider du point d'arrêt en largeur auquel mat-grid-list rendra la version à 1 colonne.

HTML:

<mat-grid-list [cols]="breakpoint" rowHeight="2:0.5" (window:resize)="onResize($event)">
  <mat-grid-tile>1</mat-grid-tile>
  <mat-grid-tile>2</mat-grid-tile>
  <mat-grid-tile>3</mat-grid-tile>
  <mat-grid-tile>4</mat-grid-tile>
  <mat-grid-tile>5</mat-grid-tile>
  <mat-grid-tile>6</mat-grid-tile>
</mat-grid-list>

TS:

ngOnInit() {
    this.breakpoint = (window.innerWidth <= 400) ? 1 : 6;
}

onResize(event) {
  this.breakpoint = (event.target.innerWidth <= 400) ? 1 : 6;
}

démonstration de Stackblitz ici

J'espère que cela t'aides!

58
Altus

J'ai aimé réponse Altus , mais j'aimerais avoir plus de points d'arrêt. J'ai donc créé une méthode simple avec quelques points d'arrêt en utilisant le service FlexLayout ObservableMedia au lieu de onResize:

import { AfterContentInit, Component, ViewChild } from '@angular/core';

import { MediaChange, ObservableMedia } from '@angular/flex-layout';
import { MatGridList } from '@angular/material';

@Component({
  selector: 'app-grid',
  templateUrl: './grid.component.html',
  styleUrls: ['./grid.component.css']
})
export class GridComponent implements AfterContentInit {
  @ViewChild('grid') grid: MatGridList;

  gridByBreakpoint = {
    xl: 8,
    lg: 6,
    md: 4,
    sm: 2,
    xs: 1
  }

  constructor(private observableMedia: ObservableMedia) {}

  ngAfterContentInit() {
    this.observableMedia.asObservable().subscribe((change: MediaChange) => {
      this.grid.cols = this.gridByBreakpoint[change.mqAlias];
    });
  }
}
<span>Breakpoint: {{grid.cols}}</span>
<mat-grid-list #grid rowHeight="2:1">
  <mat-grid-tile>1</mat-grid-tile>
  <mat-grid-tile>2</mat-grid-tile>
  <mat-grid-tile>3</mat-grid-tile>
  <mat-grid-tile>4</mat-grid-tile>
  <mat-grid-tile>5</mat-grid-tile>
  <mat-grid-tile>6</mat-grid-tile>
  <mat-grid-tile>7</mat-grid-tile>
  <mat-grid-tile>8</mat-grid-tile>
</mat-grid-list>

Voir https://stackblitz.com/edit/angular-responsive-material-grid-leocaseiro

18
Leo Caseiro

Vous pouvez utiliser la directive suivante si vous avez besoin d’une solution réutilisable:

 
import { Directive, Input, OnInit } from '@angular/core';
import { MatGridList } from '@angular/material';
import { ObservableMedia, MediaChange } from '@angular/flex-layout';

export interface IResponsiveColumnsMap {
  xs?: number;
  sm?: number;
  md?: number;
  lg?: number;
  xl?: number;
}

// Usage: <mat-grid-list [responsiveCols]="{xs: 2, sm: 2, md: 4, lg: 6, xl: 8}">
@Directive({
  selector: '[responsiveCols]'
})
export class ResponsiveColsDirective implements OnInit {
  private countBySize: IResponsiveColumnsMap = {xs: 2, sm: 2, md: 4, lg: 6, xl: 8};

  public get cols(): IResponsiveColumnsMap {
    return this.countBySize;
  }

  @Input('responsiveCols')
  public set cols(map: IResponsiveColumnsMap) {
    if (map && ('object' === (typeof map))) {
      this.countBySize = map;
    }
  }

  public constructor(
    private grid: MatGridList,
    private media: ObservableMedia
  ) {
    this.initializeColsCount();
  }

  public ngOnInit(): void {
    this.initializeColsCount();

    this.media.asObservable()
      .subscribe((changes: MediaChange) => 
        this.grid.cols = this.countBySize[changes.mqAlias]
      );
  }

  private initializeColsCount(): void {
    Object.keys(this.countBySize).some( 
      (mqAlias: string): boolean => {
        const isActive = this.media.isActive(mqAlias);

        if (isActive) {
          this.grid.cols = this.countBySize[mqAlias];
        }

        return isActive;
    });
  }
}

Excellent travail à tous!

J'ai apporté quelques améliorations supplémentaires à la réponse de Алексей Сердюков:

  • mis à jour pour flex-layout 7.0.0+
  • lors du redimensionnement de la fenêtre, la directive renvoyait dans certains cas le mauvais compte

Gist @ GitHub: https://Gist.github.com/mzellho/7fc7d5bd52a29948c47911a993547dad

0

Ajout à la réponse de @Leo Caserio, si vous obtenez une erreur lors du premier chargement de la manière suivante:

Erreur: mat-grid-list: doit indiquer le nombre de colonnes. Exemple: ...

Vous pouvez utiliser subject:

composant

@ViewChild('grid',{static:true}) grid: MatGridList;
cols:Subject<any> = new Subject();

constructor(private observableMedia: MediaObserver) { }

ngAfterContentInit() {
    this.observableMedia.asObservable().subscribe((change: MediaChange[]) => {
      this.cols.next(this.gridByBreakpoint[change[0].mqAlias]);
    });
  }

Modèle

<mat-grid-list #grid [cols]="cols | async"  rowHeight = "1:1">

Remarque: @ angular/flex-layout ": {" version ":" 8.0.0-beta.26 "}

0
Gurkan Yesilyurt