I intend to use a mat-grid-list with a set of responsive cards.
My problem is that I'm having errors with the breakpoints and I can't understand.
Can anyone help me?
ts
cardLayout = this.breakpointObserver
.observe([Breakpoints.Handset, Breakpoints.Tablet])
.pipe(
map(({ matches }) => {
if (matches) {
return {
columns: 1,
miniCard: { cols: 1, rows: 1 },
chart: { cols: 1, rows: 2 },
table: { cols: 1, rows: 4 },
};
}
return {
columns: 4,
miniCard: { cols: 1, rows: 1 },
chart: { cols: 2, rows: 2 },
table: { cols: 4, rows: 4 },
};
})
);
Error
Bad Breakpoint size
That's because you have multiple subscriptions to your observable, so the values are resolved sequentially.
So when your observable emits, first subscriber (mat-grid-list
) gets updated to the new layout, change detection is fired and DOM is updated. All of this happens BEFORE the mat-grid-tile
gets updated, so you end up with colspans from the previous layout on children while parent has a single column.
You can use *ngIf
with as
syntax to store the value locally and refer to the stored value in the children elements, e.g.
<ng-container *ngIf="cardLayout | async as layout">
<mat-grid-list [cols]="layout.columns" rowHeight="200px">
<mat-grid-tile
[colspan]="layout.miniCard.cols"
[rowspan]="layout.miniCard.rows"
>
...
</mat-grid-tile>
</mat-grid-list>
</ng-container>
This allows for a single subscription (which should be more performant as well), increases readability and removes unnecessary sequential DOM updates.
Forked stackblitz here.