-
Notifications
You must be signed in to change notification settings - Fork 822
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(GoogleMapsAPILoading): lazy load mechanism
With this optional mechanism, angular2-google-maps will load the Google Maps API script when a <sebm-google-map> component is in use for the first time. BREAKING CHANGE: You have to add the ANGULAR2_GOOGLE_MAPS_PROVIDERS to your bootstrap() method. Closes #4
- Loading branch information
1 parent
610362e
commit d05e6d3
Showing
11 changed files
with
199 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,12 @@ | ||
import {Provider} from 'angular2/angular2'; | ||
|
||
import {MapsAPILoader} from './services/maps_api_loader/maps_api_loader'; | ||
import {LazyMapsAPILoader} from './services/maps_api_loader/lazy_maps_api_loader'; | ||
|
||
// main module | ||
export * from './components'; | ||
export * from './services'; | ||
|
||
export const ANGULAR2_GOOGLE_MAPS_PROVIDERS: any[] = [ | ||
new Provider(MapsAPILoader, {useClass: LazyMapsAPILoader}), | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
export * from './components/google_map'; | ||
export * from './components/google_map_marker'; | ||
export {SebmGoogleMap} from './components/google_map'; | ||
export {SebmGoogleMapMarker} from './components/google_map_marker'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export {MapsAPILoader} from './services/maps_api_loader/maps_api_loader'; | ||
export {NoOpMapsAPILoader} from './services/maps_api_loader/noop_maps_api_loader'; | ||
export { | ||
LazyMapsAPILoader, | ||
LazyMapsAPILoaderConfig, | ||
GoogleMapsScriptProtocol | ||
} from './services/maps_api_loader/lazy_maps_api_loader'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import {Injectable, forwardRef, Optional} from 'angular2/angular2'; | ||
import {MapsAPILoader} from './maps_api_loader'; | ||
|
||
export enum GoogleMapsScriptProtocol { | ||
HTTP, | ||
HTTPS, | ||
AUTO | ||
} | ||
|
||
export class LazyMapsAPILoaderConfig { | ||
apiKey: string = null; | ||
hostAndPath: string = 'maps.googleapis.com/maps/api/js'; | ||
protocol: GoogleMapsScriptProtocol = GoogleMapsScriptProtocol.HTTPS; | ||
} | ||
|
||
const DEFAULT_CONFIGURATION = new LazyMapsAPILoaderConfig(); | ||
|
||
@Injectable() | ||
export class LazyMapsAPILoader extends MapsAPILoader { | ||
private _scriptLoadingPromise: Promise<void>; | ||
|
||
constructor(@Optional() private _config: LazyMapsAPILoaderConfig = DEFAULT_CONFIGURATION) { | ||
super(); | ||
} | ||
|
||
load(): Promise<void> { | ||
if (this._scriptLoadingPromise) { | ||
return this._scriptLoadingPromise; | ||
} | ||
|
||
const script = document.createElement('script'); | ||
script.type = 'text/javascript'; | ||
script.async = true; | ||
script.defer = true; | ||
const callbackName: string = `angular2googlemaps${new Date().getMilliseconds()}`; | ||
script.src = this._getScriptSrc(callbackName); | ||
|
||
this._scriptLoadingPromise = new Promise<void>((resolve: Function, reject: Function) => { | ||
(<any>window)[callbackName] = () => { resolve(); }; | ||
|
||
script.onerror = (error: Event) => { reject(error); }; | ||
}); | ||
|
||
document.body.appendChild(script); | ||
return this._scriptLoadingPromise; | ||
} | ||
|
||
private _getScriptSrc(callbackName: string): string { | ||
let protocolType: GoogleMapsScriptProtocol = | ||
(this._config && this._config.protocol) || DEFAULT_CONFIGURATION.protocol; | ||
let protocol: string; | ||
|
||
switch (protocolType) { | ||
case GoogleMapsScriptProtocol.AUTO: | ||
protocol = ''; | ||
break; | ||
case GoogleMapsScriptProtocol.HTTP: | ||
protocol = 'http:'; | ||
break; | ||
case GoogleMapsScriptProtocol.HTTPS: | ||
protocol = 'https:'; | ||
break; | ||
} | ||
|
||
const hostAndPath: string = | ||
(this._config && this._config.hostAndPath) || DEFAULT_CONFIGURATION.hostAndPath; | ||
const apiKey: string = (this._config && this._config.apiKey) || DEFAULT_CONFIGURATION.apiKey; | ||
const queryParams: {[key: string]: string} = {}; | ||
if (apiKey) { | ||
queryParams['key'] = apiKey; | ||
} | ||
queryParams['callback'] = callbackName; | ||
const queryParamsString: string = | ||
Object.keys(queryParams) | ||
.map( | ||
(key: string, index: number) => | ||
index === 0 ? `?${key}=${queryParams[key]}` : `&${key}=${queryParams[key]}`) | ||
.join(''); | ||
return `${protocol}//${hostAndPath}${queryParamsString}`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import {Injectable} from 'angular2/angular2'; | ||
|
||
@Injectable() | ||
export abstract class MapsAPILoader { | ||
abstract load(): Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import {MapsAPILoader} from './maps_api_loader'; | ||
|
||
/** | ||
* When using the NoOpMapsAPILoader, the Google Maps API must be added to the page via a <script> | ||
* Tag. | ||
* It's important that the Google Maps API script gets loaded first on the page. | ||
*/ | ||
export class NoOpMapsAPILoader implements MapsAPILoader { | ||
load(): Promise<void> { | ||
if (!(<any>window).google || !(<any>window).google.maps) { | ||
throw new Error( | ||
'Google Maps API not loaded on page. Make sure window.google.maps is available!'); | ||
} | ||
return Promise.resolve(); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,32 @@ | ||
import {Injectable} from 'angular2/angular2'; | ||
import {SebmGoogleMapMarker} from '../components/google_map_marker'; | ||
import {GoogleMapsAPIWrapperFactory, GoogleMapsAPIWrapper} from './google_maps_api_wrapper'; | ||
import {GoogleMapsAPIWrapper} from './google_maps_api_wrapper'; | ||
|
||
@Injectable() | ||
export class MarkerManager { | ||
private _markers: Map<SebmGoogleMapMarker, google.maps.Marker> = | ||
new Map<SebmGoogleMapMarker, google.maps.Marker>(); | ||
private _mapsAPI: GoogleMapsAPIWrapper; | ||
private _markers: Map<SebmGoogleMapMarker, Promise<google.maps.Marker>> = | ||
new Map<SebmGoogleMapMarker, Promise<google.maps.Marker>>(); | ||
|
||
constructor(f: GoogleMapsAPIWrapperFactory) { this._mapsAPI = f.getInstance(); } | ||
constructor(private _mapsWrapper: GoogleMapsAPIWrapper) {} | ||
|
||
deleteMarker(marker: SebmGoogleMapMarker) { | ||
console.log(this._markers.values()); | ||
this._markers.get(marker).setMap(null); | ||
deleteMarker(marker: SebmGoogleMapMarker): Promise<void> { | ||
let promise = this._markers.get(marker).then((m: google.maps.Marker) => m.setMap(null)); | ||
this._markers.delete(marker); | ||
return promise; | ||
} | ||
|
||
updateMarkerPosition(marker: SebmGoogleMapMarker) { | ||
this._markers.get(marker).setPosition({lat: marker.latitude, lng: marker.longitude}); | ||
updateMarkerPosition(marker: SebmGoogleMapMarker): Promise<void> { | ||
return this._markers.get(marker).then( | ||
(m: google.maps.Marker) => m.setPosition({lat: marker.latitude, lng: marker.longitude})); | ||
} | ||
|
||
updateTitle(marker: SebmGoogleMapMarker) { this._markers.get(marker).setTitle(marker.title); } | ||
updateTitle(marker: SebmGoogleMapMarker): Promise<void> { | ||
return this._markers.get(marker).then((m: google.maps.Marker) => m.setTitle(marker.title)); | ||
} | ||
|
||
addMarker(marker: SebmGoogleMapMarker) { | ||
let newMarker: google.maps.Marker = | ||
this._mapsAPI.createMarker({position: {lat: marker.latitude, lng: marker.longitude}}); | ||
this._markers.set(marker, newMarker); | ||
const markerPromise = | ||
this._mapsWrapper.createMarker({position: {lat: marker.latitude, lng: marker.longitude}}); | ||
this._markers.set(marker, markerPromise); | ||
} | ||
} |