可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am looking at basic example of md-grid-list in Angular 2.
HTML Code :
<md-grid-list cols="4" rowHeight="100px">
<md-grid-tile *ngFor="let tile of tiles"
[colspan]="tile.cols"
[rowspan]="tile.rows"
[style.background]="tile.color">
{{tile.text}}
</md-grid-tile>
</md-grid-list>
TS Code :
export class GridListDynamicExample {
tiles = [
{text: 'One', cols: 3, rows: 1, color: 'lightblue'},
{text: 'Two', cols: 1, rows: 2, color: 'lightgreen'},
{text: 'Three', cols: 1, rows: 1, color: 'lightpink'},
{text: 'Four', cols: 2, rows: 1, color: '#DDBDF1'},
];
}
The above code results in this :
How can I make the layout as "column" that is column "Two" to go below the rows(One and Four) on smaller screen size using some HTML directive or CSS?
Angular Material in Angular 1 had option to achieve by specifying "md-cols-xs="1" md-cols-sm="2" md-cols-md="4" md-cols-gt-md="6" ".
回答1:
This is the simplest Way you can achive that :)
your.component.html
<md-card class="sub-category-grid" style="padding:0px;" (window:resize)="onResize($event)">
<md-grid-list cols="{{test}}" rowHeight="1:1">
<md-grid-tile *ngFor="let item of Items">
{{item.title}}
</md-grid-tile>
</md-grid-list>
</md-card>
your.component.ts
// init this var with the default number of columns
test: any = 2;
Items: any = [
{title: "title", img_src: "../../../assets/img/-samples/raketa.png", description: "Description" },
{title: "title", img_src: "../../../assets/img/-samples/raketa.png", description: "Description" },
{title: "title", img_src: "../../../assets/img/-samples/raketa.png", description: "Description" },
{title: "title", img_src: "../../../assets/img/-samples/raketa.png", description: "Description" },
{title: "title", img_src: "../../../assets/img/-samples/raketa.png", description: "Description" },
{title: "title", img_src: "../../../assets/img/-samples/raketa.png", description: "Description" },
{title: "title", img_src: "../../../assets/img/-samples/raketa.png", description: "Description" },
{title: "title", img_src: "../../../assets/img/-samples/raketa.png", description: "Description" },
{title: "title", img_src: "../../../assets/img/-samples/raketa.png", description: "Description" }
]
constructor() { }
ngOnInit() {
}
onResize(event) {
const element = event.target.innerWidth;
console.log(element);
if (element < 950) {
this.test = 2;
}
if (element > 950) {
this.test = 3;
}
if (element < 750) {
this.test = 1;
}
}
回答2:
You can add directive to your component and then do the work in directive like this;
import { Directive, ElementRef, Input, HostListener, Output } from '@angular/core';
import * as _ from "lodash";
@Directive({ selector: '[myResponsive]' })
export class TestDirective {
@Input() tiles;
@HostListener('window:resize', ['$event'])
onResize(event) {
if (event.target.innerWidth < 980) {
_.each(this.tiles, tile => {
tile.cols = 2;
tile.rows = 1;
});
} else {
this.tiles = [
{text: 'One', cols: 3, rows: 1, color: 'lightblue'},
{text: 'Two', cols: 1, rows: 2, color: 'lightgreen'},
{text: 'Three', cols: 1, rows: 1, color: 'lightpink'},
{text: 'Four', cols: 2, rows: 1, color: '#DDBDF1'}
];
}
}
constructor(el: ElementRef) {
}
}
You also need to add your directive to app.module.ts
import { TestDirective } from "./test.directive";
@NgModule({
imports: [
...
],
declarations: [
TestDirective
]
And your HTML should be like this
<md-grid-list cols="4" rowHeight="100px">
<md-grid-tile myResponsive [(tiles)]="tiles" *ngFor="let tile of tiles"
[colspan]="tile.cols"
[rowspan]="tile.rows"
[style.background]="tile.color">
{{tile.text}}
</md-grid-tile>
</md-grid-list>
回答3:
As I understand the responsive part is currently located in flex-layout project. Some of the common utilities from this library will be moved to angular/cdk that material already uses. Flex-layout project provides an observable that you can subscribe to get notifications on break point changes - ObservableMedia. You can also use MediaService service (also from flex-layout) to assert the window sizes.
Therefore this code can be implements like that. Please notes that I use trackBy function to keep the original boxes when toggle happen.
export class AppComponent {
tiles: Array<Object>;
public columns = 4;
private subscription: Subscription;
tilesBig = [
{text: 'One', cols: 3, rows: 1, color: 'lightblue', id: 1},
{text: 'Two', cols: 1, rows: 2, color: 'lightgreen', id: 2},
{text: 'Three', cols: 1, rows: 1, color: 'lightpink', id: 3},
{text: 'Four', cols: 2, rows: 1, color: '#DDBDF1', id: 4},
];
tilesSm = [
{text: 'One', cols: 3, rows: 1, color: 'lightblue', id: 1},
{text: 'Three', cols: 1, rows: 1, color: 'lightpink', id: 3},
{text: 'Four', cols: 2, rows: 1, color: '#DDBDF1', id: 4},
{text: 'Two', cols: 3, rows: 1, color: 'lightgreen', id: 2},
];
constructor(private _media$: ObservableMedia,
private mediaService: MediaService) {
this.subscription = this._media$.subscribe((e: MediaChange) => {
this.toggle();
});
}
ngOnInit() {
this.toggle();
}
private toggle() {
const isSmall = this.mediaService.isActive('lt-md');
this.columns = isSmall ? 3 : 4;
this.tiles = isSmall ? this.tilesSm : this.tilesBig;
}
trackById(index: number, item: any): string { return item['id']; }
}
You can look at code https://stackblitz.com/edit/angular-t325tj?embed=1&file=app/app.component.ts
回答4:
Making responsive design in angular 4 is not as simple as it is in bootstrape. To make md-grid-list responsive or should change view according to device width then we need to use flex layout library
To have clearity about how reponsive things work in angular visit below links
visit http://brianflove.com/2017/05/03/responsive-angular/
demo http://run.plnkr.co/preview/cja10xr7900083b5wx6srd0r6/