簡體   English   中英

Angular 5 Mat-grid 列表響應式

[英]Angular 5 Mat-grid list responsive

我創建了第 6 列的網格列表,我希望網格標題在小屏幕設備上占據 100% 的寬度。 現在它也在小屏幕上創建 6 列

預期:一個網格標題僅在移動設備上占用 100% 的空間

您必須根據屏幕寬度動態設置mat-grid-listcols屬性。 您必須決定mat-grid-list將呈現 1 列版本的寬度斷點。

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 演示在這里

希望這有幫助!

我喜歡Altus answer ,但我想要更多斷點。 所以我使用 FlexLayout ObservableMedia 服務而不是 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>

請參閱https://stackblitz.com/edit/angular-responsive-material-grid-leocaseiro

如果您需要可重用的解決方案,您可以使用以下指令:

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

我使用 BreakpointObserver 來實現這一點。

請參閱角度文檔: https : //material.angular.io/cdk/layout/overview

 import { Component, OnInit} from '@angular/core'; import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; @Component({ selector: 'app-index', templateUrl: './index.component.html', styleUrls: ['./index.component.css'] }) export class IndexComponent implements OnInit { cols : number; gridByBreakpoint = { xl: 3, lg: 3, md: 3, sm: 2, xs: 1 } constructor(private breakpointObserver: BreakpointObserver) { this.breakpointObserver.observe([ Breakpoints.XSmall, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge, ]).subscribe(result => { if (result.matches) { if (result.breakpoints[Breakpoints.XSmall]) { this.cols = this.gridByBreakpoint.xs; } if (result.breakpoints[Breakpoints.Small]) { this.cols = this.gridByBreakpoint.sm; } if (result.breakpoints[Breakpoints.Medium]) { this.cols = this.gridByBreakpoint.md; } if (result.breakpoints[Breakpoints.Large]) { this.cols = this.gridByBreakpoint.lg; } if (result.breakpoints[Breakpoints.XLarge]) { this.cols = this.gridByBreakpoint.xl; } } }); } ngOnInit() { } }
 <mat-grid-list #grid [cols]="cols" rowHeight="20:11" gutterSize="20px" > <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>

大家辛苦了!

我對 Алексей Сердюков 的回答做了一些進一步的改進:

  • 為 flex-layout 7.0.0+ 更新
  • 調整窗口大小時,指令在某些情況下返回錯誤的計數

要點@GitHub: https : //gist.github.com/mzellho/7fc7d5bd52a29948c47911a993547dad

靈感來自格雷戈里的回答。

如果您希望避免顯式訂閱 observable,您可以使用異步管道。

 import { Component, OnInit} from '@angular/core'; import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { Observable } from 'rxjs'; import { map, shareReplay } from 'rxjs/operators'; @Component({ selector: 'app-index', templateUrl: './index.component.html', styleUrls: ['./index.component.css'] }) export class IndexComponent { cols$: Observable<number> = this.breakpointObserver .observe([Breakpoints.Small, Breakpoints.XSmall]) .pipe( map((result) => { if (result.breakpoints[Breakpoints.XSmall]) { return 1; } else if (result.breakpoints[Breakpoints.Small]) { return 2; } else { return 3; } }), shareReplay() ); constructor(private breakpointObserver: BreakpointObserver) { } }
 <mat-grid-list [cols]="cols$ | async" rowHeight="20:11" gutterSize="20px" > <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>

除了@Leo Caserio 的回答之外,如果您在第一次加載時遇到如下錯誤:

錯誤:mat-grid-list:必須傳入列數。 例子:...

您可以使用subject

組件

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

模板

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM