@@ -13,7 +13,6 @@ import {
1313 ChangeDetectionStrategy ,
1414 Component ,
1515 ElementRef ,
16- EventEmitter ,
1716 Input ,
1817 OnChanges ,
1918 OnDestroy ,
@@ -27,6 +26,7 @@ import {
2726import { isPlatformBrowser } from '@angular/common' ;
2827import { BehaviorSubject , combineLatest , Observable , Subject } from 'rxjs' ;
2928import { map , shareReplay , take , takeUntil } from 'rxjs/operators' ;
29+ import { MapEventManager } from '../map-event-manager' ;
3030
3131interface GoogleMapsWindow extends Window {
3232 google ?: typeof google ;
@@ -64,6 +64,20 @@ export const DEFAULT_WIDTH = '500px';
6464 encapsulation : ViewEncapsulation . None ,
6565} )
6666export class GoogleMap implements OnChanges , OnInit , OnDestroy {
67+ private _eventManager = new MapEventManager ( ) ;
68+
69+ /** Whether we're currently rendering inside a browser. */
70+ private _isBrowser : boolean ;
71+ private _googleMapChanges : Observable < google . maps . Map > ;
72+
73+ private readonly _options = new BehaviorSubject < google . maps . MapOptions > ( DEFAULT_OPTIONS ) ;
74+ private readonly _center =
75+ new BehaviorSubject < google . maps . LatLngLiteral | google . maps . LatLng | undefined > ( undefined ) ;
76+ private readonly _zoom = new BehaviorSubject < number | undefined > ( undefined ) ;
77+ private readonly _destroy = new Subject < void > ( ) ;
78+ private _mapEl : HTMLElement ;
79+ _googleMap : UpdatedGoogleMap ;
80+
6781 @Input ( ) height = DEFAULT_HEIGHT ;
6882
6983 @Input ( ) width = DEFAULT_WIDTH ;
@@ -85,125 +99,127 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
8599 * See
86100 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.bounds_changed
87101 */
88- @Output ( ) boundsChanged = new EventEmitter < void > ( ) ;
102+ @Output ( )
103+ boundsChanged : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'bounds_changed' ) ;
89104
90105 /**
91106 * See
92107 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.center_changed
93108 */
94- @Output ( ) centerChanged = new EventEmitter < void > ( ) ;
109+ @Output ( )
110+ centerChanged : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'center_changed' ) ;
95111
96112 /**
97113 * See
98114 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.click
99115 */
100- @Output ( ) mapClick = new EventEmitter < google . maps . MouseEvent | google . maps . IconMouseEvent > ( ) ;
116+ @Output ( )
117+ mapClick : Observable < google . maps . MouseEvent | google . maps . IconMouseEvent > =
118+ this . _eventManager . getLazyEmitter < google . maps . MouseEvent | google . maps . IconMouseEvent > ( 'click' ) ;
101119
102120 /**
103121 * See
104122 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.dblclick
105123 */
106- @Output ( ) mapDblclick = new EventEmitter < google . maps . MouseEvent > ( ) ;
124+ @Output ( )
125+ mapDblclick : Observable < google . maps . MouseEvent > =
126+ this . _eventManager . getLazyEmitter < google . maps . MouseEvent > ( 'dblclick' ) ;
107127
108128 /**
109129 * See
110130 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.drag
111131 */
112- @Output ( ) mapDrag = new EventEmitter < void > ( ) ;
132+ @Output ( ) mapDrag : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'drag' ) ;
113133
114134 /**
115135 * See
116136 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.dragend
117137 */
118- @Output ( ) mapDragend = new EventEmitter < void > ( ) ;
138+ @Output ( ) mapDragend : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'dragend' ) ;
119139
120140 /**
121141 * See
122142 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.dragstart
123143 */
124- @Output ( ) mapDragstart = new EventEmitter < void > ( ) ;
144+ @Output ( ) mapDragstart : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'dragstart' ) ;
125145
126146 /**
127147 * See
128148 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.heading_changed
129149 */
130- @Output ( ) headingChanged = new EventEmitter < void > ( ) ;
150+ @Output ( )
151+ headingChanged : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'heading_changed' ) ;
131152
132153 /**
133154 * See
134155 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.idle
135156 */
136- @Output ( ) idle = new EventEmitter < void > ( ) ;
157+ @Output ( ) idle : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'idle' ) ;
137158
138159 /**
139160 * See
140161 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.maptypeid_changed
141162 */
142- @Output ( ) maptypeidChanged = new EventEmitter < void > ( ) ;
163+ @Output ( )
164+ maptypeidChanged : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'maptypeid_changed' ) ;
143165
144166 /**
145167 * See
146168 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.mousemove
147169 */
148- @Output ( ) mapMousemove = new EventEmitter < google . maps . MouseEvent > ( ) ;
170+ @Output ( )
171+ mapMousemove : Observable < google . maps . MouseEvent > =
172+ this . _eventManager . getLazyEmitter < google . maps . MouseEvent > ( 'mousemove' ) ;
149173
150174 /**
151175 * See
152176 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.mouseout
153177 */
154- @Output ( ) mapMouseout = new EventEmitter < google . maps . MouseEvent > ( ) ;
178+ @Output ( )
179+ mapMouseout : Observable < google . maps . MouseEvent > =
180+ this . _eventManager . getLazyEmitter < google . maps . MouseEvent > ( 'mouseout' ) ;
155181
156182 /**
157183 * See
158184 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.mouseover
159185 */
160- @Output ( ) mapMouseover = new EventEmitter < google . maps . MouseEvent > ( ) ;
186+ @Output ( )
187+ mapMouseover : Observable < google . maps . MouseEvent > =
188+ this . _eventManager . getLazyEmitter < google . maps . MouseEvent > ( 'mouseover' ) ;
161189
162190 /**
163191 * See
164192 * developers.google.com/maps/documentation/javascript/reference/map#Map.projection_changed
165193 */
166- @Output ( ) projectionChanged = new EventEmitter < void > ( ) ;
194+ @Output ( )
195+ projectionChanged : Observable < void > =
196+ this . _eventManager . getLazyEmitter < void > ( 'projection_changed' ) ;
167197
168198 /**
169199 * See
170200 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.rightclick
171201 */
172- @Output ( ) mapRightclick = new EventEmitter < google . maps . MouseEvent > ( ) ;
202+ @Output ( )
203+ mapRightclick : Observable < google . maps . MouseEvent > =
204+ this . _eventManager . getLazyEmitter < google . maps . MouseEvent > ( 'rightclick' ) ;
173205
174206 /**
175207 * See
176208 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.tilesloaded
177209 */
178- @Output ( ) tilesloaded = new EventEmitter < void > ( ) ;
210+ @Output ( ) tilesloaded : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'tilesloaded' ) ;
179211
180212 /**
181213 * See
182214 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.tilt_changed
183215 */
184- @Output ( ) tiltChanged = new EventEmitter < void > ( ) ;
216+ @Output ( ) tiltChanged : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'tilt_changed' ) ;
185217
186218 /**
187219 * See
188220 * https://developers.google.com/maps/documentation/javascript/reference/map#Map.zoom_changed
189221 */
190- @Output ( ) zoomChanged = new EventEmitter < void > ( ) ;
191-
192- private _mapEl : HTMLElement ;
193- _googleMap : UpdatedGoogleMap ;
194-
195- /** Whether we're currently rendering inside a browser. */
196- private _isBrowser : boolean ;
197- private _googleMapChanges ! : Observable < google . maps . Map > ;
198-
199- private _listeners : google . maps . MapsEventListener [ ] = [ ] ;
200-
201- private readonly _options = new BehaviorSubject < google . maps . MapOptions > ( DEFAULT_OPTIONS ) ;
202- private readonly _center =
203- new BehaviorSubject < google . maps . LatLngLiteral | google . maps . LatLng | undefined > ( undefined ) ;
204- private readonly _zoom = new BehaviorSubject < number | undefined > ( undefined ) ;
205-
206- private readonly _destroy = new Subject < void > ( ) ;
222+ @Output ( ) zoomChanged : Observable < void > = this . _eventManager . getLazyEmitter < void > ( 'zoomChanged' ) ;
207223
208224 constructor (
209225 private readonly _elementRef : ElementRef ,
@@ -238,13 +254,10 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
238254 if ( this . _isBrowser ) {
239255 this . _mapEl = this . _elementRef . nativeElement . querySelector ( '.map-container' ) ! ;
240256 this . _setSize ( ) ;
241-
242- const combinedOptionsChanges = this . _combineOptions ( ) ;
243-
244- this . _googleMapChanges = this . _initializeMap ( combinedOptionsChanges ) ;
257+ this . _googleMapChanges = this . _initializeMap ( this . _combineOptions ( ) ) ;
245258 this . _googleMapChanges . subscribe ( ( googleMap : google . maps . Map ) => {
246259 this . _googleMap = googleMap as UpdatedGoogleMap ;
247- this . _initializeEventHandlers ( this . _googleMap ) ;
260+ this . _eventManager . setTarget ( this . _googleMap ) ;
248261 } ) ;
249262
250263 this . _watchForOptionsChanges ( ) ;
@@ -254,9 +267,9 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
254267 }
255268
256269 ngOnDestroy ( ) {
270+ this . _eventManager . destroy ( ) ;
257271 this . _destroy . next ( ) ;
258272 this . _destroy . complete ( ) ;
259- this . _clearListeners ( ) ;
260273 }
261274
262275 /**
@@ -472,64 +485,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
472485 } ) ;
473486 }
474487
475- private _initializeEventHandlers ( googleMap : UpdatedGoogleMap ) {
476- // Ensure that we don't leak if called multiple times.
477- this . _clearListeners ( ) ;
478-
479- const eventHandlers = new Map < string , EventEmitter < void > > ( [
480- [ 'bounds_changed' , this . boundsChanged ] ,
481- [ 'center_changed' , this . centerChanged ] ,
482- [ 'drag' , this . mapDrag ] ,
483- [ 'dragend' , this . mapDragend ] ,
484- [ 'dragstart' , this . mapDragstart ] ,
485- [ 'heading_changed' , this . headingChanged ] ,
486- [ 'idle' , this . idle ] ,
487- [ 'maptypeid_changed' , this . maptypeidChanged ] ,
488- [ 'projection_changed' , this . projectionChanged ] ,
489- [ 'tilesloaded' , this . tilesloaded ] ,
490- [ 'tilt_changed' , this . tiltChanged ] ,
491- [ 'zoomChanged' , this . zoomChanged ] ,
492- ] ) ;
493- const mouseEventHandlers = new Map < string , EventEmitter < google . maps . MouseEvent > > ( [
494- [ 'dblclick' , this . mapDblclick ] ,
495- [ 'mousemove' , this . mapMousemove ] ,
496- [ 'mouseout' , this . mapMouseout ] ,
497- [ 'mouseover' , this . mapMouseover ] ,
498- [ 'rightclick' , this . mapRightclick ] ,
499- ] ) ;
500- eventHandlers . forEach ( ( eventHandler : EventEmitter < void > , name : string ) => {
501- if ( eventHandler . observers . length > 0 ) {
502- this . _listeners . push ( googleMap . addListener ( name , ( ) => {
503- eventHandler . emit ( ) ;
504- } ) ) ;
505- }
506- } ) ;
507- mouseEventHandlers . forEach (
508- ( eventHandler : EventEmitter < google . maps . MouseEvent > , name : string ) => {
509- if ( eventHandler . observers . length > 0 ) {
510- this . _listeners . push (
511- googleMap . addListener ( name , ( event : google . maps . MouseEvent ) => {
512- eventHandler . emit ( event ) ;
513- } ) ) ;
514- }
515- } ) ;
516- if ( this . mapClick . observers . length > 0 ) {
517- this . _listeners . push ( googleMap . addListener (
518- 'click' , ( event : google . maps . MouseEvent | google . maps . IconMouseEvent ) => {
519- this . mapClick . emit ( event ) ;
520- } ) ) ;
521- }
522- }
523-
524- /** Clears all currently-registered event listeners. */
525- private _clearListeners ( ) {
526- for ( let listener of this . _listeners ) {
527- listener . remove ( ) ;
528- }
529-
530- this . _listeners = [ ] ;
531- }
532-
488+ /** Asserts that the map has been initialized. */
533489 private _assertInitialized ( ) {
534490 if ( ! this . _googleMap ) {
535491 throw Error ( 'Cannot access Google Map information before the API has been initialized. ' +
0 commit comments