Angular 5 Mat-grid列表响应

时间:2018-01-29 02:39:58

标签: angular angular-material angular5

我创建了第6列的网格列表,我想在小屏幕设备上获得100%宽度的网格标题。现在它在小屏幕上创建了6列

预期: 一个网格标题仅占移动设备空间的100%

7 个答案:

答案 0 :(得分:44)

您必须根据屏幕宽度动态设置cols的{​​{1}}属性。您必须决定mat-grid-list呈现1列版本的宽度断点。

HTML:

mat-grid-list

TS:

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

Stackblitz demo here

希望这有帮助!

答案 1 :(得分:16)

我喜欢Altus answer,但我希望有更多断点。所以我使用FlexLayout ObservableMedia服务而不是onResize创建了一个包含一些断点的简单方法:

&#13;
&#13;
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];
    });
  }
}
&#13;
<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>
&#13;
&#13;
&#13;

请参阅https://stackblitz.com/edit/angular-responsive-material-grid-leocaseiro

答案 2 :(得分:11)

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

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

答案 3 :(得分:2)

我使用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>

答案 4 :(得分:0)

大家辛苦了!

我对АлексейСердюков的答案做了进一步的改进:

  • 已针对弹性版式7.0.0+更新
  • 调整窗口大小时,指令在某些情况下返回了错误的计数

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

答案 5 :(得分:0)

如果您在第一次加载时遇到以下错误,请添加@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“:{”版本“:” 8.0.0-beta.26“}

答案 6 :(得分:0)

灵感来自 Grégory 的回答。

如果您希望避免显式订阅 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>