@@ -155,45 +155,46 @@ function GridListDirective($interpolate, $mdConstant, $mdGridLayout, $mdMedia) {
155155 * Invokes the layout engine, and uses its results to lay out our
156156 * tile elements.
157157 *
158- * @param {boolean } tilesAdded Whether tiles have been added since the last
159- * layout. This is to avoid situations where tiles are replaced with
160- * properties identical to their removed counterparts.
158+ * @param {boolean } tilesInvalidated Whether tiles have been
159+ * added/removed/moved since the last layout. This is to avoid situations
160+ * where tiles are replaced with properties identical to their removed
161+ * counterparts.
161162 */
162- function layoutDelegate ( tilesAdded ) {
163+ function layoutDelegate ( tilesInvalidated ) {
164+ var tiles = getTileElements ( ) ;
163165 var props = {
164- tileSpans : getTileSpans ( ) ,
166+ tileSpans : getTileSpans ( tiles ) ,
165167 colCount : getColumnCount ( ) ,
166168 rowMode : getRowMode ( ) ,
167169 rowHeight : getRowHeight ( ) ,
168170 gutter : getGutter ( )
169171 } ;
170172
171- if ( ! tilesAdded && angular . equals ( props , lastLayoutProps ) ) {
173+ if ( ! tilesInvalidated && angular . equals ( props , lastLayoutProps ) ) {
172174 return ;
173175 }
174176
175- var tiles = getTileElements ( ) ,
176- performance =
177- $mdGridLayout ( props . colCount , props . tileSpans , tiles )
178- . map ( function ( tilePositions , rowCount ) {
177+ var performance =
178+ $mdGridLayout ( props . colCount , props . tileSpans , tiles )
179+ . map ( function ( tilePositions , rowCount ) {
180+ return {
181+ grid : {
182+ element : element ,
183+ style : getGridStyle ( props . colCount , rowCount ,
184+ props . gutter , props . rowMode , props . rowHeight )
185+ } ,
186+ tiles : tilePositions . map ( function ( ps , i ) {
179187 return {
180- grid : {
181- element : element ,
182- style : getGridStyle ( props . colCount , rowCount ,
183- props . gutter , props . rowMode , props . rowHeight )
184- } ,
185- tiles : tilePositions . map ( function ( ps , i ) {
186- return {
187- element : angular . element ( tiles [ i ] ) ,
188- style : getTileStyle ( ps . position , ps . spans ,
189- props . colCount , props . rowCount ,
190- props . gutter , props . rowMode , props . rowHeight )
191- }
192- } )
188+ element : angular . element ( tiles [ i ] ) ,
189+ style : getTileStyle ( ps . position , ps . spans ,
190+ props . colCount , props . rowCount ,
191+ props . gutter , props . rowMode , props . rowHeight )
193192 }
194193 } )
195- . reflow ( )
196- . performance ( ) ;
194+ }
195+ } )
196+ . reflow ( )
197+ . performance ( ) ;
197198
198199 // Report layout
199200 scope . mdOnLayout ( {
@@ -345,20 +346,23 @@ function GridListDirective($interpolate, $mdConstant, $mdGridLayout, $mdMedia) {
345346 }
346347
347348 function getTileElements ( ) {
348- return ctrl . tiles . map ( function ( tile ) { return tile . element } ) ;
349+ return [ ] . filter . call ( element . children ( ) , function ( ele ) {
350+ return ele . tagName == 'MD-GRID-TILE' ;
351+ } ) ;
349352 }
350353
351354 /**
352355 * Gets an array of objects containing the rowspan and colspan for each tile.
353356 * @returns {Array<{row: number, col: number}> }
354357 */
355- function getTileSpans ( ) {
356- return ctrl . tiles . map ( function ( tile ) {
358+ function getTileSpans ( tileElements ) {
359+ return [ ] . map . call ( tileElements , function ( ele ) {
360+ var ctrl = angular . element ( ele ) . controller ( 'mdGridTile' ) ;
357361 return {
358362 row : parseInt (
359- $mdMedia . getResponsiveAttribute ( tile . attrs , 'md-rowspan' ) , 10 ) || 1 ,
363+ $mdMedia . getResponsiveAttribute ( ctrl . $ attrs, 'md-rowspan' ) , 10 ) || 1 ,
360364 col : parseInt (
361- $mdMedia . getResponsiveAttribute ( tile . attrs , 'md-colspan' ) , 10 ) || 1
365+ $mdMedia . getResponsiveAttribute ( ctrl . $ attrs, 'md-colspan' ) , 10 ) || 1
362366 } ;
363367 } ) ;
364368 }
@@ -407,58 +411,33 @@ function GridListDirective($interpolate, $mdConstant, $mdGridLayout, $mdMedia) {
407411
408412/* @ngInject */
409413function GridListController ( $timeout ) {
410- this . invalidated = false ;
411- this . tilesAdded = false ;
414+ this . layoutInvalidated = false ;
415+ this . tilesInvalidated = false ;
412416 this . $timeout_ = $timeout ;
413- this . tiles = [ ] ;
414417 this . layoutDelegate = angular . noop ;
415418}
416419
417420GridListController . prototype = {
418- addTile : function ( tileElement , tileAttrs , idx ) {
419- var tile = { element : tileElement , attrs : tileAttrs } ;
420- if ( angular . isUndefined ( idx ) ) {
421- this . tiles . push ( tile ) ;
422- } else {
423- this . tiles . splice ( idx , 0 , tile ) ;
424- }
425- this . tilesAdded = true ;
426- this . invalidateLayout ( ) ;
427- } ,
428-
429- removeTile : function ( tileElement , tileAttrs ) {
430- var idx = this . _findTileIndex ( tileAttrs ) ;
431- if ( idx === - 1 ) {
432- return ;
433- }
434- this . tiles . splice ( idx , 1 ) ;
421+ invalidateTiles : function ( ) {
422+ this . tilesInvalidated = true ;
435423 this . invalidateLayout ( ) ;
436424 } ,
437425
438426 invalidateLayout : function ( ) {
439- if ( this . invalidated ) {
427+ if ( this . layoutInvalidated ) {
440428 return ;
441429 }
442- this . invalidated = true ;
430+ this . layoutInvalidated = true ;
443431 this . $timeout_ ( angular . bind ( this , this . layout ) ) ;
444432 } ,
445433
446434 layout : function ( ) {
447435 try {
448- this . layoutDelegate ( this . tilesAdded ) ;
436+ this . layoutDelegate ( this . tilesInvalidated ) ;
449437 } finally {
450- this . invalidated = false ;
451- this . tilesAdded = false ;
438+ this . layoutInvalidated = false ;
439+ this . tilesInvalidated = false ;
452440 }
453- } ,
454-
455- _findTileIndex : function ( tileAttrs ) {
456- for ( var i = 0 ; i < this . tiles . length ; i ++ ) {
457- if ( this . tiles [ i ] . attrs == tileAttrs ) {
458- return i ;
459- }
460- }
461- return - 1 ;
462441 }
463442} ;
464443
@@ -724,6 +703,10 @@ function GridTileDirective($mdMedia) {
724703 template : '<figure ng-transclude></figure>' ,
725704 transclude : true ,
726705 scope : { } ,
706+ // Simple controller that exposes attributes to the grid directive
707+ controller : function ( $attrs ) {
708+ this . $attrs = $attrs ;
709+ } ,
727710 link : postLink
728711 } ;
729712
@@ -736,24 +719,25 @@ function GridTileDirective($mdMedia) {
736719 attrs , angular . bind ( gridCtrl , gridCtrl . invalidateLayout ) ) ;
737720
738721 // Tile registration/deregistration
739- // TODO(shyndman): Kind of gross to access parent scope like this.
740- // Consider other options.
741- gridCtrl . addTile ( element , attrs , scope . $parent . $index ) ;
722+ gridCtrl . invalidateTiles ( ) ;
742723 scope . $on ( '$destroy' , function ( ) {
743724 unwatchAttrs ( ) ;
744- gridCtrl . removeTile ( element , attrs ) ;
725+ gridCtrl . invalidateLayout ( ) ;
745726 } ) ;
746727
747728 if ( angular . isDefined ( scope . $parent . $index ) ) {
748729 scope . $watch ( function ( ) { return scope . $parent . $index ; } ,
749730 function indexChanged ( newIdx , oldIdx ) {
750- gridCtrl . removeTile ( element , attrs ) ;
751- gridCtrl . addTile ( element , attrs , newIdx ) ;
731+ if ( newIdx === oldIdx ) {
732+ return ;
733+ }
734+ gridCtrl . invalidateTiles ( ) ;
752735 } ) ;
753736 }
754737 }
755738}
756739
740+
757741function GridTileCaptionDirective ( ) {
758742 return {
759743 template : '<figcaption ng-transclude></figcaption>' ,
0 commit comments