@@ -28,9 +28,10 @@ import {LayoutDirective, LAYOUT_VALUES} from './layout';
2828 * 'layout-padding' styling directive
2929 * Defines padding of child elements in a layout container
3030 */
31- @Directive ( { selector : `
31+ @Directive ( {
32+ selector : `
3233 [fxLayoutGap],
33- [fxLayoutGap.xs]
34+ [fxLayoutGap.xs],
3435 [fxLayoutGap.gt-xs],
3536 [fxLayoutGap.sm],
3637 [fxLayoutGap.gt-sm]
@@ -39,28 +40,58 @@ import {LayoutDirective, LAYOUT_VALUES} from './layout';
3940 [fxLayoutGap.lg],
4041 [fxLayoutGap.gt-lg],
4142 [fxLayoutGap.xl]
42- ` } )
43+ `
44+ } )
4345export class LayoutGapDirective extends BaseFxDirective implements AfterContentInit , OnChanges ,
44- OnDestroy {
46+ OnDestroy {
4547 private _layout = 'row' ; // default flex-direction
4648 private _layoutWatcher : Subscription ;
49+ private _observer : MutationObserver ;
4750
48- @Input ( 'fxLayoutGap' ) set gap ( val ) { this . _cacheInput ( 'gap' , val ) ; }
49- @Input ( 'fxLayoutGap.xs' ) set gapXs ( val ) { this . _cacheInput ( 'gapXs' , val ) ; }
50- @Input ( 'fxLayoutGap.gt-xs' ) set gapGtXs ( val ) { this . _cacheInput ( 'gapGtXs' , val ) ; } ;
51- @Input ( 'fxLayoutGap.sm' ) set gapSm ( val ) { this . _cacheInput ( 'gapSm' , val ) ; } ;
52- @Input ( 'fxLayoutGap.gt-sm' ) set gapGtSm ( val ) { this . _cacheInput ( 'gapGtSm' , val ) ; } ;
53- @Input ( 'fxLayoutGap.md' ) set gapMd ( val ) { this . _cacheInput ( 'gapMd' , val ) ; } ;
54- @Input ( 'fxLayoutGap.gt-md' ) set gapGtMd ( val ) { this . _cacheInput ( 'gapGtMd' , val ) ; } ;
55- @Input ( 'fxLayoutGap.lg' ) set gapLg ( val ) { this . _cacheInput ( 'gapLg' , val ) ; } ;
56- @Input ( 'fxLayoutGap.gt-lg' ) set gapGtLg ( val ) { this . _cacheInput ( 'gapGtLg' , val ) ; } ;
57- @Input ( 'fxLayoutGap.xl' ) set gapXl ( val ) { this . _cacheInput ( 'gapXl' , val ) ; } ;
58-
59- constructor (
60- monitor : MediaMonitor ,
61- elRef : ElementRef ,
62- renderer : Renderer ,
63- @Optional ( ) @Self ( ) container : LayoutDirective ) {
51+ @Input ( 'fxLayoutGap' ) set gap ( val ) {
52+ this . _cacheInput ( 'gap' , val ) ;
53+ }
54+
55+ @Input ( 'fxLayoutGap.xs' ) set gapXs ( val ) {
56+ this . _cacheInput ( 'gapXs' , val ) ;
57+ }
58+
59+ @Input ( 'fxLayoutGap.gt-xs' ) set gapGtXs ( val ) {
60+ this . _cacheInput ( 'gapGtXs' , val ) ;
61+ } ;
62+
63+ @Input ( 'fxLayoutGap.sm' ) set gapSm ( val ) {
64+ this . _cacheInput ( 'gapSm' , val ) ;
65+ } ;
66+
67+ @Input ( 'fxLayoutGap.gt-sm' ) set gapGtSm ( val ) {
68+ this . _cacheInput ( 'gapGtSm' , val ) ;
69+ } ;
70+
71+ @Input ( 'fxLayoutGap.md' ) set gapMd ( val ) {
72+ this . _cacheInput ( 'gapMd' , val ) ;
73+ } ;
74+
75+ @Input ( 'fxLayoutGap.gt-md' ) set gapGtMd ( val ) {
76+ this . _cacheInput ( 'gapGtMd' , val ) ;
77+ } ;
78+
79+ @Input ( 'fxLayoutGap.lg' ) set gapLg ( val ) {
80+ this . _cacheInput ( 'gapLg' , val ) ;
81+ } ;
82+
83+ @Input ( 'fxLayoutGap.gt-lg' ) set gapGtLg ( val ) {
84+ this . _cacheInput ( 'gapGtLg' , val ) ;
85+ } ;
86+
87+ @Input ( 'fxLayoutGap.xl' ) set gapXl ( val ) {
88+ this . _cacheInput ( 'gapXl' , val ) ;
89+ } ;
90+
91+ constructor ( monitor : MediaMonitor ,
92+ elRef : ElementRef ,
93+ renderer : Renderer ,
94+ @Optional ( ) @Self ( ) container : LayoutDirective ) {
6495 super ( monitor , elRef , renderer ) ;
6596
6697 if ( container ) { // Subscribe to layout direction changes
@@ -83,23 +114,43 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
83114 * mql change events to onMediaQueryChange handlers
84115 */
85116 ngAfterContentInit ( ) {
117+ this . _watchContentChanges ( ) ;
86118 this . _listenForMediaQueryChanges ( 'gap' , '0' , ( changes : MediaChange ) => {
87119 this . _updateWithValue ( changes . value ) ;
88120 } ) ;
89121 this . _updateWithValue ( ) ;
90122 }
91123
92124 ngOnDestroy ( ) {
93- super . ngOnDestroy ( ) ;
94- if ( this . _layoutWatcher ) {
95- this . _layoutWatcher . unsubscribe ( ) ;
96- }
97- }
125+ super . ngOnDestroy ( ) ;
126+ if ( this . _layoutWatcher ) {
127+ this . _layoutWatcher . unsubscribe ( ) ;
128+ }
129+ if ( this . _observer ) {
130+ this . _observer . disconnect ( ) ;
131+ }
132+ }
98133
99134 // *********************************************
100135 // Protected methods
101136 // *********************************************
102137
138+ /**
139+ * Watch for child nodes to be added... and apply the layout gap styles to each.
140+ * NOTE: this does NOT! differentiate between viewChildren and contentChildren
141+ */
142+ private _watchContentChanges ( ) {
143+ let onMutationCallback = ( mutations ) => {
144+ // update gap styles only for 'addedNodes' events
145+ mutations
146+ . filter ( ( it : MutationRecord ) => it . addedNodes && it . addedNodes . length )
147+ . map ( ( ) => this . _updateWithValue ( ) ) ;
148+ } ;
149+
150+ this . _observer = new MutationObserver ( onMutationCallback ) ;
151+ this . _observer . observe ( this . _elementRef . nativeElement , { childList : true } ) ;
152+ }
153+
103154 /**
104155 * Cache the parent container 'flex-direction' and update the 'margin' styles
105156 */
@@ -108,7 +159,6 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
108159 if ( ! LAYOUT_VALUES . find ( x => x === this . _layout ) ) {
109160 this . _layout = 'row' ;
110161 }
111-
112162 this . _updateWithValue ( ) ;
113163 }
114164
@@ -121,11 +171,18 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
121171 value = this . _mqActivation . activatedInput ;
122172 }
123173
124- // For each `element` child, set the padding styles...
174+ // Reset 1st child element to 0px gap
125175 let items = this . childrenNodes
126- . filter ( el => ( el . nodeType === 1 ) ) // only Element types
127- . filter ( ( el , j ) => j > 0 ) ; // skip first element since gaps are needed
128- this . _applyStyleToElements ( this . _buildCSS ( value ) , items ) ;
176+ . filter ( el => ( el . nodeType === 1 ) ) // only Element types
177+ . filter ( ( el , j ) => j == 0 ) ;
178+ this . _applyStyleToElements ( this . _buildCSS ( 0 ) , items ) ;
179+
180+ // For each `element` child, set the padding styles...
181+ items = this . childrenNodes
182+ . filter ( el => ( el . nodeType === 1 ) ) // only Element types
183+ . filter ( ( el , j ) => j > 0 ) ; // skip first element since gaps are needed
184+ this . _applyStyleToElements ( this . _buildCSS ( value ) , items ) ;
185+
129186 }
130187
131188 /**
0 commit comments