49 votes

Liste angulaire 5 mat-grid 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.

103voto

Altus Points 1102

Vous devez définir l' cols attribut de l' mat-grid-list dynamiquement en fonction de la largeur de l'écran. Vous devez décider de la largeur de point d'arrêt est l' mat-grid-list le rendu de la colonne 1 de la version.

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;
}

Stackblitz démo ici

Espérons que cette aide!

35voto

Leo Caseiro Points 673

J'ai aimé Altus réponse, mais je voudrais avoir plus de points d'arrêt. J'ai donc créé une méthode simple avec des points d'arrêt à l'aide de FlexLayout ObservableMedia service 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

16voto

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;
    });
  }
} 

2voto

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

-1voto

Gurkan Yesilyurt Points 1874

Ajout à la réponse de @Leo Caserio, si vous obtenez une erreur lors du premier chargement, comme suit:

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 "}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X