@@ -22,10 +22,10 @@ import {
22
22
Inject ,
23
23
PLATFORM_ID ,
24
24
NgZone ,
25
+ SimpleChanges ,
25
26
} from '@angular/core' ;
26
27
import { isPlatformBrowser } from '@angular/common' ;
27
- import { BehaviorSubject , combineLatest , Observable , Subject } from 'rxjs' ;
28
- import { map , shareReplay , take , takeUntil } from 'rxjs/operators' ;
28
+ import { Observable } from 'rxjs' ;
29
29
import { MapEventManager } from '../map-event-manager' ;
30
30
31
31
interface GoogleMapsWindow extends Window {
@@ -57,13 +57,6 @@ export const DEFAULT_WIDTH = '500px';
57
57
} )
58
58
export class GoogleMap implements OnChanges , OnInit , OnDestroy {
59
59
private _eventManager : MapEventManager = new MapEventManager ( this . _ngZone ) ;
60
- private _googleMapChanges : Observable < google . maps . Map > ;
61
-
62
- private readonly _options = new BehaviorSubject < google . maps . MapOptions > ( DEFAULT_OPTIONS ) ;
63
- private readonly _center =
64
- new BehaviorSubject < google . maps . LatLngLiteral | google . maps . LatLng | undefined > ( undefined ) ;
65
- private readonly _zoom = new BehaviorSubject < number | undefined > ( undefined ) ;
66
- private readonly _destroy = new Subject < void > ( ) ;
67
60
private _mapEl : HTMLElement ;
68
61
69
62
/**
@@ -90,16 +83,21 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
90
83
91
84
@Input ( )
92
85
set center ( center : google . maps . LatLngLiteral | google . maps . LatLng ) {
93
- this . _center . next ( center ) ;
86
+ this . _center = center ;
94
87
}
88
+ private _center : google . maps . LatLngLiteral | google . maps . LatLng ;
89
+
95
90
@Input ( )
96
91
set zoom ( zoom : number ) {
97
- this . _zoom . next ( zoom ) ;
92
+ this . _zoom = zoom ;
98
93
}
94
+ private _zoom : number ;
95
+
99
96
@Input ( )
100
97
set options ( options : google . maps . MapOptions ) {
101
- this . _options . next ( options || DEFAULT_OPTIONS ) ;
98
+ this . _options = options || DEFAULT_OPTIONS ;
102
99
}
100
+ private _options = DEFAULT_OPTIONS ;
103
101
104
102
/**
105
103
* See
@@ -246,10 +244,30 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
246
244
}
247
245
}
248
246
249
- ngOnChanges ( ) {
250
- this . _setSize ( ) ;
251
- if ( this . googleMap && this . mapTypeId ) {
252
- this . googleMap . setMapTypeId ( this . mapTypeId ) ;
247
+ ngOnChanges ( changes : SimpleChanges ) {
248
+ if ( changes [ 'height' ] || changes [ 'width' ] ) {
249
+ this . _setSize ( ) ;
250
+ }
251
+
252
+ const googleMap = this . googleMap ;
253
+
254
+ if ( googleMap ) {
255
+ if ( changes [ 'options' ] && this . _options ) {
256
+ googleMap . setOptions ( this . _options ) ;
257
+ }
258
+
259
+ if ( changes [ 'center' ] && this . _center ) {
260
+ googleMap . setCenter ( this . _center ) ;
261
+ }
262
+
263
+ // Note that the zoom can be zero.
264
+ if ( changes [ 'zoom' ] && this . _zoom != null ) {
265
+ googleMap . setZoom ( this . _zoom ) ;
266
+ }
267
+
268
+ if ( changes [ 'mapTypeId' ] && this . mapTypeId ) {
269
+ googleMap . setMapTypeId ( this . mapTypeId ) ;
270
+ }
253
271
}
254
272
}
255
273
@@ -258,22 +276,19 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
258
276
if ( this . _isBrowser ) {
259
277
this . _mapEl = this . _elementRef . nativeElement . querySelector ( '.map-container' ) ! ;
260
278
this . _setSize ( ) ;
261
- this . _googleMapChanges = this . _initializeMap ( this . _combineOptions ( ) ) ;
262
- this . _googleMapChanges . subscribe ( ( googleMap : google . maps . Map ) => {
263
- this . googleMap = googleMap ;
264
- this . _eventManager . setTarget ( this . googleMap ) ;
265
- } ) ;
266
279
267
- this . _watchForOptionsChanges ( ) ;
268
- this . _watchForCenterChanges ( ) ;
269
- this . _watchForZoomChanges ( ) ;
280
+ // Create the object outside the zone so its events don't trigger change detection.
281
+ // We'll bring it back in inside the `MapEventManager` only for the events that the
282
+ // user has subscribed to.
283
+ this . _ngZone . runOutsideAngular ( ( ) => {
284
+ this . googleMap = new google . maps . Map ( this . _mapEl , this . _combineOptions ( ) ) ;
285
+ } ) ;
286
+ this . _eventManager . setTarget ( this . googleMap ) ;
270
287
}
271
288
}
272
289
273
290
ngOnDestroy ( ) {
274
291
this . _eventManager . destroy ( ) ;
275
- this . _destroy . next ( ) ;
276
- this . _destroy . complete ( ) ;
277
292
}
278
293
279
294
/**
@@ -443,60 +458,16 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
443
458
}
444
459
445
460
/** Combines the center and zoom and the other map options into a single object */
446
- private _combineOptions ( ) : Observable < google . maps . MapOptions > {
447
- return combineLatest ( [ this . _options , this . _center , this . _zoom ] )
448
- . pipe ( map ( ( [ options , center , zoom ] ) => {
449
- const combinedOptions : google . maps . MapOptions = {
450
- ...options ,
451
- // It's important that we set **some** kind of `center` and `zoom`, otherwise
452
- // Google Maps will render a blank rectangle which looks broken.
453
- center : center || options . center || DEFAULT_OPTIONS . center ,
454
- zoom : zoom ?? options . zoom ?? DEFAULT_OPTIONS . zoom ,
455
- mapTypeId : this . mapTypeId
456
- } ;
457
- return combinedOptions ;
458
- } ) ) ;
459
- }
460
-
461
- private _initializeMap ( optionsChanges : Observable < google . maps . MapOptions > ) :
462
- Observable < google . maps . Map > {
463
- return optionsChanges . pipe (
464
- take ( 1 ) ,
465
- map ( options => {
466
- // Create the object outside the zone so its events don't trigger change detection.
467
- // We'll bring it back in inside the `MapEventManager` only for the events that the
468
- // user has subscribed to.
469
- return this . _ngZone . runOutsideAngular ( ( ) => new google . maps . Map ( this . _mapEl , options ) ) ;
470
- } ) ,
471
- shareReplay ( 1 ) ) ;
472
- }
473
-
474
- private _watchForOptionsChanges ( ) {
475
- combineLatest ( [ this . _googleMapChanges , this . _options ] )
476
- . pipe ( takeUntil ( this . _destroy ) )
477
- . subscribe ( ( [ googleMap , options ] ) => {
478
- googleMap . setOptions ( options ) ;
479
- } ) ;
480
- }
481
-
482
- private _watchForCenterChanges ( ) {
483
- combineLatest ( [ this . _googleMapChanges , this . _center ] )
484
- . pipe ( takeUntil ( this . _destroy ) )
485
- . subscribe ( ( [ googleMap , center ] ) => {
486
- if ( center ) {
487
- googleMap . setCenter ( center ) ;
488
- }
489
- } ) ;
490
- }
491
-
492
- private _watchForZoomChanges ( ) {
493
- combineLatest ( [ this . _googleMapChanges , this . _zoom ] )
494
- . pipe ( takeUntil ( this . _destroy ) )
495
- . subscribe ( ( [ googleMap , zoom ] ) => {
496
- if ( zoom !== undefined ) {
497
- googleMap . setZoom ( zoom ) ;
498
- }
499
- } ) ;
461
+ private _combineOptions ( ) : google . maps . MapOptions {
462
+ const options = this . _options ;
463
+ return {
464
+ ...options ,
465
+ // It's important that we set **some** kind of `center` and `zoom`, otherwise
466
+ // Google Maps will render a blank rectangle which looks broken.
467
+ center : this . _center || options . center || DEFAULT_OPTIONS . center ,
468
+ zoom : this . _zoom ?? options . zoom ?? DEFAULT_OPTIONS . zoom ,
469
+ mapTypeId : this . mapTypeId
470
+ } ;
500
471
}
501
472
502
473
/** Asserts that the map has been initialized. */
0 commit comments