diff --git a/src/lib/grid-list/grid-list.spec.ts b/src/lib/grid-list/grid-list.spec.ts
index 6f556b40bbcc..048d430d8545 100644
--- a/src/lib/grid-list/grid-list.spec.ts
+++ b/src/lib/grid-list/grid-list.spec.ts
@@ -64,13 +64,13 @@ describe('MdGridList', () => {
it('should use a ratio row height if passed in', () => {
let fixture = TestBed.createComponent(GirdListWithRowHeightRatio);
- fixture.componentInstance.heightRatio = '4:1';
+ fixture.componentInstance.rowHeight = '4:1';
fixture.detectChanges();
let tile = fixture.debugElement.query(By.directive(MdGridTile));
expect(getStyle(tile, 'padding-top')).toBe('100px');
- fixture.componentInstance.heightRatio = '2:1';
+ fixture.componentInstance.rowHeight = '2:1';
fixture.detectChanges();
expect(getStyle(tile, 'padding-top')).toBe('200px');
@@ -257,7 +257,7 @@ describe('MdGridList', () => {
it('should not use calc() that evaluates to 0', () => {
const fixture = TestBed.createComponent(GirdListWithRowHeightRatio);
- fixture.componentInstance.heightRatio = '4:1';
+ fixture.componentInstance.rowHeight = '4:1';
fixture.detectChanges();
const firstTile = fixture.debugElement.query(By.directive(MdGridTile)).nativeElement;
@@ -265,6 +265,28 @@ describe('MdGridList', () => {
expect(firstTile.style.marginTop).toBe('0px');
expect(firstTile.style.left).toBe('0px');
});
+
+ it('should reset the old styles when switching to a new tile styler', () => {
+ const fixture = TestBed.createComponent(GirdListWithRowHeightRatio);
+
+ fixture.componentInstance.rowHeight = '4:1';
+ fixture.detectChanges();
+
+ const list = fixture.debugElement.query(By.directive(MdGridList));
+ const tile = fixture.debugElement.query(By.directive(MdGridTile));
+
+ expect(getStyle(tile, 'padding-top')).toBe('100px');
+ expect(getStyle(list, 'padding-bottom')).toBe('100px');
+
+ fixture.componentInstance.rowHeight = '400px';
+ fixture.detectChanges();
+
+ expect(getStyle(tile, 'padding-top')).toBe('0px', 'Expected tile padding to be reset.');
+ expect(getStyle(list, 'padding-bottom')).toBe('0px', 'Expected list padding to be reset.');
+ expect(getStyle(tile, 'top')).toBe('0px');
+ expect(getStyle(tile, 'height')).toBe('400px');
+ });
+
});
@@ -306,12 +328,12 @@ class GridListWithUnspecifiedRowHeight { }
@Component({template: `
-
+
`})
class GirdListWithRowHeightRatio {
- heightRatio: string;
+ rowHeight: string;
}
@Component({template: `
diff --git a/src/lib/grid-list/grid-list.ts b/src/lib/grid-list/grid-list.ts
index 20cc6befd653..5a5581995835 100644
--- a/src/lib/grid-list/grid-list.ts
+++ b/src/lib/grid-list/grid-list.ts
@@ -85,8 +85,12 @@ export class MdGridList implements OnInit, AfterContentChecked {
/** Set internal representation of row height from the user-provided value. */
@Input()
set rowHeight(value: string | number) {
- this._rowHeight = coerceToString(value);
- this._setTileStyler();
+ const newValue = coerceToString(value);
+
+ if (newValue !== this._rowHeight) {
+ this._rowHeight = newValue;
+ this._setTileStyler(this._rowHeight);
+ }
}
ngOnInit() {
@@ -106,36 +110,40 @@ export class MdGridList implements OnInit, AfterContentChecked {
private _checkCols() {
if (!this.cols) {
throw Error(`md-grid-list: must pass in number of columns. ` +
- `Example: `);
+ `Example: `);
}
}
/** Default to equal width:height if rowHeight property is missing */
private _checkRowHeight(): void {
if (!this._rowHeight) {
- this._tileStyler = new RatioTileStyler('1:1');
+ this._setTileStyler('1:1');
}
}
/** Creates correct Tile Styler subtype based on rowHeight passed in by user */
- private _setTileStyler(): void {
- if (this._rowHeight === MD_FIT_MODE) {
+ private _setTileStyler(rowHeight: string): void {
+ if (this._tileStyler) {
+ this._tileStyler.reset(this);
+ }
+
+ if (rowHeight === MD_FIT_MODE) {
this._tileStyler = new FitTileStyler();
- } else if (this._rowHeight && this._rowHeight.indexOf(':') > -1) {
- this._tileStyler = new RatioTileStyler(this._rowHeight);
+ } else if (rowHeight && rowHeight.indexOf(':') > -1) {
+ this._tileStyler = new RatioTileStyler(rowHeight);
} else {
- this._tileStyler = new FixedTileStyler(this._rowHeight);
+ this._tileStyler = new FixedTileStyler(rowHeight);
}
}
/** Computes and applies the size and position for all children grid tiles. */
private _layoutTiles(): void {
- let tracker = new TileCoordinator(this.cols, this._tiles);
- let direction = this._dir ? this._dir.value : 'ltr';
+ const tracker = new TileCoordinator(this.cols, this._tiles);
+ const direction = this._dir ? this._dir.value : 'ltr';
this._tileStyler.init(this.gutterSize, tracker, this.cols, direction);
this._tiles.forEach((tile, index) => {
- let pos = tracker.positions[index];
+ const pos = tracker.positions[index];
this._tileStyler.setStyle(tile, pos.row, pos.col);
});
@@ -143,7 +151,7 @@ export class MdGridList implements OnInit, AfterContentChecked {
}
/** Sets style on the main grid-list element, given the style name and value. */
- _setListStyle(style: [string, string] | null): void {
+ _setListStyle(style: [string, string | null] | null): void {
if (style) {
this._renderer.setStyle(this._element.nativeElement, style[0], style[1]);
}
diff --git a/src/lib/grid-list/grid-tile.ts b/src/lib/grid-list/grid-tile.ts
index 24a9dc21c78d..d2f57a9ef46a 100644
--- a/src/lib/grid-list/grid-tile.ts
+++ b/src/lib/grid-list/grid-tile.ts
@@ -52,7 +52,7 @@ export class MdGridTile {
* Sets the style of the grid-tile element. Needs to be set manually to avoid
* "Changed after checked" errors that would occur with HostBinding.
*/
- _setStyle(property: string, value: string): void {
+ _setStyle(property: string, value: any): void {
this._renderer.setStyle(this._element.nativeElement, property, value);
}
}
diff --git a/src/lib/grid-list/tile-styler.ts b/src/lib/grid-list/tile-styler.ts
index 6c781e3c7e67..36a897e1d583 100644
--- a/src/lib/grid-list/tile-styler.ts
+++ b/src/lib/grid-list/tile-styler.ts
@@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
+import {MdGridList} from './grid-list';
import {MdGridTile} from './grid-tile';
import {TileCoordinator} from './tile-coordinator';
@@ -139,6 +140,13 @@ export abstract class TileStyler {
* @docs-private
*/
getComputedHeight(): [string, string] | null { return null; }
+
+ /**
+ * Called when the tile styler is swapped out with a different one. To be used for cleanup.
+ * @param list Grid list that the styler was attached to.
+ * @docs-private
+ */
+ abstract reset(list: MdGridList);
}
@@ -166,6 +174,15 @@ export class FixedTileStyler extends TileStyler {
'height', calc(`${this.getTileSpan(this.fixedRowHeight)} + ${this.getGutterSpan()}`)
];
}
+
+ reset(list: MdGridList) {
+ list._setListStyle(['height', null]);
+
+ list._tiles.forEach(tile => {
+ tile._setStyle('top', null);
+ tile._setStyle('height', null);
+ });
+ }
}
@@ -203,8 +220,17 @@ export class RatioTileStyler extends TileStyler {
];
}
+ reset(list: MdGridList) {
+ list._setListStyle(['padding-bottom', null]);
+
+ list._tiles.forEach(tile => {
+ tile._setStyle('margin-top', null);
+ tile._setStyle('padding-top', null);
+ });
+ }
+
private _parseRatio(value: string): void {
- let ratioParts = value.split(':');
+ const ratioParts = value.split(':');
if (ratioParts.length !== 2) {
throw Error(`md-grid-list: invalid ratio given for row-height: "${value}"`);
@@ -237,6 +263,12 @@ export class FitTileStyler extends TileStyler {
tile._setStyle('height', calc(this.getTileSize(baseTileHeight, tile.rowspan)));
}
+ reset(list: MdGridList) {
+ list._tiles.forEach(tile => {
+ tile._setStyle('top', null);
+ tile._setStyle('height', null);
+ });
+ }
}