Angular 5 Mat-grid 列表响应
Angular 5 Mat-grid list responsive
我创建了带有第 6 列的网格列表,我希望网格标题在小屏幕设备上占据 100% 的宽度。现在它也在小屏幕上创建 6 列
预计:
一个 grid-title 仅在移动设备上占据 space 的 100%
您必须根据屏幕宽度动态设置 mat-grid-list
的 cols
属性。您必须决定 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;
}
希望对您有所帮助!
我喜欢,但我想要更多的断点。所以我使用 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;
});
}
}
大家辛苦了!
我对 Алексей Сердюков 的回答做了一些进一步的改进:
- 已更新为 flex-layout 7.0.0+
- 调整 window 大小时,指令在某些情况下返回了错误的计数
要点@GitHub:https://gist.github.com/mzellho/7fc7d5bd52a29948c47911a993547dad
除了@Leo Caserio 的回答,如果您在第一次加载时遇到如下错误:
Error: mat-grid-list: must pass in number of columns. Example: ...
您可以使用 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" }
我使用了 BreakpointObserver 来实现这一点。
请参阅 angular 文档: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>
灵感来自 Grégory 的回答。
如果您希望避免显式订阅可观察对象,您可以使用异步管道。
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>
我创建了带有第 6 列的网格列表,我希望网格标题在小屏幕设备上占据 100% 的宽度。现在它也在小屏幕上创建 6 列
预计: 一个 grid-title 仅在移动设备上占据 space 的 100%
您必须根据屏幕宽度动态设置 mat-grid-list
的 cols
属性。您必须决定 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;
}
希望对您有所帮助!
我喜欢
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;
});
}
}
大家辛苦了!
我对 Алексей Сердюков 的回答做了一些进一步的改进:
- 已更新为 flex-layout 7.0.0+
- 调整 window 大小时,指令在某些情况下返回了错误的计数
要点@GitHub:https://gist.github.com/mzellho/7fc7d5bd52a29948c47911a993547dad
除了@Leo Caserio 的回答,如果您在第一次加载时遇到如下错误:
Error: mat-grid-list: must pass in number of columns. Example: ...
您可以使用 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" }
我使用了 BreakpointObserver 来实现这一点。
请参阅 angular 文档: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>
灵感来自 Grégory 的回答。
如果您希望避免显式订阅可观察对象,您可以使用异步管道。
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>