Skip to content

Commit 87d607e

Browse files
crisbetotinayuangao
authored andcommitted
fix(grid-list): styles not cleared when switching to a different styling mode (#6660)
Fixes the old styles not being cleared when switching between styling modes in the grid list (e.g. going for proportions to a fixed height). Fixes #4047.
1 parent d0eef62 commit 87d607e

File tree

4 files changed

+82
-20
lines changed

4 files changed

+82
-20
lines changed

src/lib/grid-list/grid-list.spec.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ describe('MdGridList', () => {
6464
it('should use a ratio row height if passed in', () => {
6565
let fixture = TestBed.createComponent(GirdListWithRowHeightRatio);
6666

67-
fixture.componentInstance.heightRatio = '4:1';
67+
fixture.componentInstance.rowHeight = '4:1';
6868
fixture.detectChanges();
6969

7070
let tile = fixture.debugElement.query(By.directive(MdGridTile));
7171
expect(getStyle(tile, 'padding-top')).toBe('100px');
7272

73-
fixture.componentInstance.heightRatio = '2:1';
73+
fixture.componentInstance.rowHeight = '2:1';
7474
fixture.detectChanges();
7575

7676
expect(getStyle(tile, 'padding-top')).toBe('200px');
@@ -257,14 +257,36 @@ describe('MdGridList', () => {
257257
it('should not use calc() that evaluates to 0', () => {
258258
const fixture = TestBed.createComponent(GirdListWithRowHeightRatio);
259259

260-
fixture.componentInstance.heightRatio = '4:1';
260+
fixture.componentInstance.rowHeight = '4:1';
261261
fixture.detectChanges();
262262

263263
const firstTile = fixture.debugElement.query(By.directive(MdGridTile)).nativeElement;
264264

265265
expect(firstTile.style.marginTop).toBe('0px');
266266
expect(firstTile.style.left).toBe('0px');
267267
});
268+
269+
it('should reset the old styles when switching to a new tile styler', () => {
270+
const fixture = TestBed.createComponent(GirdListWithRowHeightRatio);
271+
272+
fixture.componentInstance.rowHeight = '4:1';
273+
fixture.detectChanges();
274+
275+
const list = fixture.debugElement.query(By.directive(MdGridList));
276+
const tile = fixture.debugElement.query(By.directive(MdGridTile));
277+
278+
expect(getStyle(tile, 'padding-top')).toBe('100px');
279+
expect(getStyle(list, 'padding-bottom')).toBe('100px');
280+
281+
fixture.componentInstance.rowHeight = '400px';
282+
fixture.detectChanges();
283+
284+
expect(getStyle(tile, 'padding-top')).toBe('0px', 'Expected tile padding to be reset.');
285+
expect(getStyle(list, 'padding-bottom')).toBe('0px', 'Expected list padding to be reset.');
286+
expect(getStyle(tile, 'top')).toBe('0px');
287+
expect(getStyle(tile, 'height')).toBe('400px');
288+
});
289+
268290
});
269291

270292

@@ -306,12 +328,12 @@ class GridListWithUnspecifiedRowHeight { }
306328

307329
@Component({template: `
308330
<div style="width:400px">
309-
<md-grid-list cols="1" [rowHeight]="heightRatio">
331+
<md-grid-list cols="1" [rowHeight]="rowHeight">
310332
<md-grid-tile></md-grid-tile>
311333
</md-grid-list>
312334
</div>`})
313335
class GirdListWithRowHeightRatio {
314-
heightRatio: string;
336+
rowHeight: string;
315337
}
316338

317339
@Component({template: `

src/lib/grid-list/grid-list.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,12 @@ export class MdGridList implements OnInit, AfterContentChecked {
8585
/** Set internal representation of row height from the user-provided value. */
8686
@Input()
8787
set rowHeight(value: string | number) {
88-
this._rowHeight = coerceToString(value);
89-
this._setTileStyler();
88+
const newValue = coerceToString(value);
89+
90+
if (newValue !== this._rowHeight) {
91+
this._rowHeight = newValue;
92+
this._setTileStyler(this._rowHeight);
93+
}
9094
}
9195

9296
ngOnInit() {
@@ -106,44 +110,48 @@ export class MdGridList implements OnInit, AfterContentChecked {
106110
private _checkCols() {
107111
if (!this.cols) {
108112
throw Error(`md-grid-list: must pass in number of columns. ` +
109-
`Example: <md-grid-list cols="3">`);
113+
`Example: <md-grid-list cols="3">`);
110114
}
111115
}
112116

113117
/** Default to equal width:height if rowHeight property is missing */
114118
private _checkRowHeight(): void {
115119
if (!this._rowHeight) {
116-
this._tileStyler = new RatioTileStyler('1:1');
120+
this._setTileStyler('1:1');
117121
}
118122
}
119123

120124
/** Creates correct Tile Styler subtype based on rowHeight passed in by user */
121-
private _setTileStyler(): void {
122-
if (this._rowHeight === MD_FIT_MODE) {
125+
private _setTileStyler(rowHeight: string): void {
126+
if (this._tileStyler) {
127+
this._tileStyler.reset(this);
128+
}
129+
130+
if (rowHeight === MD_FIT_MODE) {
123131
this._tileStyler = new FitTileStyler();
124-
} else if (this._rowHeight && this._rowHeight.indexOf(':') > -1) {
125-
this._tileStyler = new RatioTileStyler(this._rowHeight);
132+
} else if (rowHeight && rowHeight.indexOf(':') > -1) {
133+
this._tileStyler = new RatioTileStyler(rowHeight);
126134
} else {
127-
this._tileStyler = new FixedTileStyler(this._rowHeight);
135+
this._tileStyler = new FixedTileStyler(rowHeight);
128136
}
129137
}
130138

131139
/** Computes and applies the size and position for all children grid tiles. */
132140
private _layoutTiles(): void {
133-
let tracker = new TileCoordinator(this.cols, this._tiles);
134-
let direction = this._dir ? this._dir.value : 'ltr';
141+
const tracker = new TileCoordinator(this.cols, this._tiles);
142+
const direction = this._dir ? this._dir.value : 'ltr';
135143
this._tileStyler.init(this.gutterSize, tracker, this.cols, direction);
136144

137145
this._tiles.forEach((tile, index) => {
138-
let pos = tracker.positions[index];
146+
const pos = tracker.positions[index];
139147
this._tileStyler.setStyle(tile, pos.row, pos.col);
140148
});
141149

142150
this._setListStyle(this._tileStyler.getComputedHeight());
143151
}
144152

145153
/** Sets style on the main grid-list element, given the style name and value. */
146-
_setListStyle(style: [string, string] | null): void {
154+
_setListStyle(style: [string, string | null] | null): void {
147155
if (style) {
148156
this._renderer.setStyle(this._element.nativeElement, style[0], style[1]);
149157
}

src/lib/grid-list/grid-tile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class MdGridTile {
5252
* Sets the style of the grid-tile element. Needs to be set manually to avoid
5353
* "Changed after checked" errors that would occur with HostBinding.
5454
*/
55-
_setStyle(property: string, value: string): void {
55+
_setStyle(property: string, value: any): void {
5656
this._renderer.setStyle(this._element.nativeElement, property, value);
5757
}
5858
}

src/lib/grid-list/tile-styler.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {MdGridList} from './grid-list';
910
import {MdGridTile} from './grid-tile';
1011
import {TileCoordinator} from './tile-coordinator';
1112

@@ -139,6 +140,13 @@ export abstract class TileStyler {
139140
* @docs-private
140141
*/
141142
getComputedHeight(): [string, string] | null { return null; }
143+
144+
/**
145+
* Called when the tile styler is swapped out with a different one. To be used for cleanup.
146+
* @param list Grid list that the styler was attached to.
147+
* @docs-private
148+
*/
149+
abstract reset(list: MdGridList);
142150
}
143151

144152

@@ -166,6 +174,15 @@ export class FixedTileStyler extends TileStyler {
166174
'height', calc(`${this.getTileSpan(this.fixedRowHeight)} + ${this.getGutterSpan()}`)
167175
];
168176
}
177+
178+
reset(list: MdGridList) {
179+
list._setListStyle(['height', null]);
180+
181+
list._tiles.forEach(tile => {
182+
tile._setStyle('top', null);
183+
tile._setStyle('height', null);
184+
});
185+
}
169186
}
170187

171188

@@ -203,8 +220,17 @@ export class RatioTileStyler extends TileStyler {
203220
];
204221
}
205222

223+
reset(list: MdGridList) {
224+
list._setListStyle(['padding-bottom', null]);
225+
226+
list._tiles.forEach(tile => {
227+
tile._setStyle('margin-top', null);
228+
tile._setStyle('padding-top', null);
229+
});
230+
}
231+
206232
private _parseRatio(value: string): void {
207-
let ratioParts = value.split(':');
233+
const ratioParts = value.split(':');
208234

209235
if (ratioParts.length !== 2) {
210236
throw Error(`md-grid-list: invalid ratio given for row-height: "${value}"`);
@@ -237,6 +263,12 @@ export class FitTileStyler extends TileStyler {
237263
tile._setStyle('height', calc(this.getTileSize(baseTileHeight, tile.rowspan)));
238264
}
239265

266+
reset(list: MdGridList) {
267+
list._tiles.forEach(tile => {
268+
tile._setStyle('top', null);
269+
tile._setStyle('height', null);
270+
});
271+
}
240272
}
241273

242274

0 commit comments

Comments
 (0)