Skip to content

Commit

Permalink
feat(google-maps): add map-marker component (angular#16964)
Browse files Browse the repository at this point in the history
* Refactor google-maps module to have a single entry-point,
@angular/google-maps, instead of a separate one for every component.
* Add GoogleMap and MapMarker components to index for the google maps
module.
  • Loading branch information
mbehrlich authored and jelbourn committed Sep 6, 2019
1 parent 44b8a47 commit c8ceae5
Show file tree
Hide file tree
Showing 28 changed files with 913 additions and 126 deletions.
6 changes: 0 additions & 6 deletions packages.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@ MATERIAL_SCSS_LIBS = [
for p in MATERIAL_PACKAGES
]

GOOGLE_MAPS_PACKAGES = [
"google-map",
]

GOOGLE_MAPS_TARGETS = ["//src/google-maps"] + ["//src/google-maps/%s" % p for p in GOOGLE_MAPS_PACKAGES]

MATERIAL_EXPERIMENTAL_PACKAGES = [
"mdc-button",
"mdc-card",
Expand Down
2 changes: 1 addition & 1 deletion src/dev-app/google-map/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ng_module(
srcs = glob(["**/*.ts"]),
assets = ["google-map-demo.html"],
deps = [
"//src/google-maps/google-map",
"//src/google-maps",
"@npm//@angular/router",
],
)
4 changes: 2 additions & 2 deletions src/dev-app/google-map/google-map-demo-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
import {CommonModule} from '@angular/common';
import {HttpClientJsonpModule, HttpClientModule} from '@angular/common/http';
import {NgModule} from '@angular/core';
import {GoogleMapModule} from '@angular/google-maps/google-map';
import {GoogleMapsModule} from '@angular/google-maps';
import {RouterModule} from '@angular/router';

import {GoogleMapDemo} from './google-map-demo';

@NgModule({
imports: [
CommonModule,
GoogleMapModule,
GoogleMapsModule,
HttpClientJsonpModule,
HttpClientModule,
RouterModule.forChild([{path: '', component: GoogleMapDemo}]),
Expand Down
9 changes: 8 additions & 1 deletion src/dev-app/google-map/google-map-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
[center]="center"
[zoom]="zoom"
(mapClick)="handleClick($event)"
(mapMousemove)="handleMove($event)"></google-map>
(mapMousemove)="handleMove($event)"
(mapRightclick)="handleRightclick()">
<map-marker></map-marker>
<map-marker *ngFor="let markerPosition of markerPositions"
[position]="markerPosition"
[options]="markerOptions"
(mapClick)="clickMarker($event)"></map-marker>
</google-map>

<div>Latitude: {{display?.lat}}</div>
<div>Longitude: {{display?.lng}}</div>
13 changes: 12 additions & 1 deletion src/dev-app/google-map/google-map-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export class GoogleMapDemo {
isReady = false;

center = {lat: 24, lng: 12};
markerOptions = {draggable: false};
markerPositions: google.maps.LatLngLiteral[] = [];
zoom = 4;
display?: google.maps.LatLngLiteral;

Expand All @@ -30,10 +32,19 @@ export class GoogleMapDemo {
}

handleClick(event: google.maps.MouseEvent) {
this.center = event.latLng.toJSON();
this.markerPositions.push(event.latLng.toJSON());
}

handleMove(event: google.maps.MouseEvent) {
this.display = event.latLng.toJSON();
}

clickMarker(event: google.maps.MouseEvent) {
console.log(this.markerOptions);
this.markerOptions = {draggable: true};
}

handleRightclick() {
this.markerPositions.pop();
}
}
8 changes: 1 addition & 7 deletions src/dev-app/system-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ var MATERIAL_PACKAGES = [
'tree',
];

var GOOGLE_MAPS_PACKAGES = [
'google-map',
];

var MATERIAL_EXPERIMENTAL_PACKAGES = [
'mdc-button',
'mdc-card',
Expand Down Expand Up @@ -103,9 +99,7 @@ MATERIAL_EXPERIMENTAL_PACKAGES.forEach(function(pkgName) {
MATERIAL_PACKAGES.forEach(function(pkgName) {
configureEntryPoint('material', pkgName);
});
GOOGLE_MAPS_PACKAGES.forEach(function(pkgName) {
configureEntryPoint('google-maps', pkgName);
});
configureEntryPoint('google-maps');
configureEntryPoint('youtube-player');

/** Configures the specified package and its entry-point. */
Expand Down
2 changes: 1 addition & 1 deletion src/dev-app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@angular/cdk-experimental/*": ["../cdk-experimental/*"],
"@angular/cdk-experimental": ["../cdk-experimental"],
"@angular/material-moment-adapter": ["../material-moment-adapter/public-api.ts"],
"@angular/google-maps/*": ["../google-maps/*"],
"@angular/google-maps": ["../google-maps"],
"@angular/material-examples": ["../../dist/packages/material-examples"]
}
},
Expand Down
19 changes: 10 additions & 9 deletions src/google-maps/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
package(default_visibility = ["//visibility:public"])

load("//:packages.bzl", "GOOGLE_MAPS_PACKAGES", "GOOGLE_MAPS_TARGETS", "ROLLUP_GLOBALS")
load("//:packages.bzl", "ROLLUP_GLOBALS")
load("//tools:defaults.bzl", "ng_module", "ng_package")

# Root "@angular/google-maps" entry-point that does not re-export individual entry-points.
ng_module(
name = "google-maps",
srcs = glob(
["*.ts"],
exclude = ["**/*.spec.ts"],
),
module_name = "@angular/google-maps",
deps = ["//src/google-maps/%s" % p for p in GOOGLE_MAPS_PACKAGES] + [
deps = [
"//src/google-maps/google-map",
"//src/google-maps/map-marker",
"@npm//@angular/core",
"@npm//@types/googlemaps",
],
)

filegroup(
name = "overviews",
srcs = ["//src/google-maps/%s:overview" % name for name in GOOGLE_MAPS_PACKAGES],
)

# Creates the @angular/google-maps package published to npm
ng_package(
name = "npm_package",
srcs = ["package.json"],
entry_point = ":public-api.ts",
entry_point_name = "google-maps",
globals = ROLLUP_GLOBALS,
deps = GOOGLE_MAPS_TARGETS,
deps = [":google-maps"],
)

filegroup(
name = "source-files",
srcs = glob(["**/*.ts"]),
)
11 changes: 3 additions & 8 deletions src/google-maps/google-map/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package(default_visibility = ["//visibility:public"])

load(
"//tools:defaults.bzl",
"markdown_to_html",
"ng_module",
"ng_test_library",
"ng_web_test_suite",
Expand All @@ -14,8 +13,8 @@ ng_module(
["**/*.ts"],
exclude = ["**/*.spec.ts"],
),
module_name = "@angular/google-maps/google-map",
deps = [
"//src/google-maps/map-marker",
"@npm//@angular/core",
"@npm//@types/googlemaps",
"@npm//rxjs",
Expand All @@ -30,7 +29,8 @@ ng_test_library(
),
deps = [
":google-map",
"//src/google-maps/google-map/testing",
"//src/google-maps/map-marker",
"//src/google-maps/testing",
"@npm//@angular/platform-browser",
],
)
Expand All @@ -40,11 +40,6 @@ ng_web_test_suite(
deps = [":unit_test_sources"],
)

markdown_to_html(
name = "overview",
srcs = [":google-map.md"],
)

filegroup(
name = "source-files",
srcs = glob(["**/*.ts"]),
Expand Down
16 changes: 9 additions & 7 deletions src/google-maps/google-map/google-map-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/

import {NgModule} from '@angular/core';
import {GoogleMap} from './google-map';
import {NgModule} from '@angular/core';

@NgModule({
exports: [GoogleMap],
declarations: [GoogleMap],
})
export class GoogleMapModule {}
import {GoogleMap} from './google-map';

@NgModule({
exports: [GoogleMap],
declarations: [GoogleMap],
})
export class GoogleMapModule {
}
Empty file.
37 changes: 28 additions & 9 deletions src/google-maps/google-map/google-map.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import {Component} from '@angular/core';
import {async, TestBed} from '@angular/core/testing';
import {By} from '@angular/platform-browser';

import {MapMarker, MapMarkerModule} from '../map-marker/index';
import {
createMapConstructorSpy,
createMapSpy,
TestingWindow
} from '../testing/fake-google-map-utils';

import {
DEFAULT_HEIGHT,
DEFAULT_OPTIONS,
Expand All @@ -10,11 +17,6 @@ import {
GoogleMapModule,
UpdatedGoogleMap
} from './index';
import {
createMapConstructorSpy,
createMapSpy,
TestingWindow
} from './testing/fake-google-map-utils';

/** Represents boundaries of a map to be used in tests. */
const testBounds: google.maps.LatLngBoundsLiteral = {
Expand All @@ -36,7 +38,10 @@ describe('GoogleMap', () => {

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [GoogleMapModule],
imports: [
GoogleMapModule,
MapMarkerModule,
],
declarations: [TestApp],
});
}));
Expand Down Expand Up @@ -237,6 +242,18 @@ describe('GoogleMap', () => {
expect(mapSpy.addListener).not.toHaveBeenCalledWith('tilt_changed', jasmine.any(Function));
expect(mapSpy.addListener).not.toHaveBeenCalledWith('zoom_changed', jasmine.any(Function));
});

it('calls setMap on child marker components', () => {
mapSpy = createMapSpy(DEFAULT_OPTIONS);
createMapConstructorSpy(mapSpy).and.callThrough();

const fixture = TestBed.createComponent(TestApp);
const markerComponent = fixture.debugElement.query(By.directive(MapMarker)).componentInstance;
spyOn(markerComponent, '_setMap').and.callThrough();
fixture.detectChanges();

expect(markerComponent._setMap).toHaveBeenCalledWith(mapSpy);
});
});

@Component({
Expand All @@ -246,9 +263,11 @@ describe('GoogleMap', () => {
[center]="center"
[zoom]="zoom"
[options]="options"
(mapClick)="handleClick"
(centerChanged)="handleCenterChanged"
(mapRightclick)="handleRightclick"></google-map>`,
(mapClick)="handleClick($event)"
(centerChanged)="handleCenterChanged()"
(mapRightclick)="handleRightclick($event)">
<map-marker></map-marker>
</google-map>`,
})
class TestApp {
height?: string;
Expand Down
40 changes: 33 additions & 7 deletions src/google-maps/google-map/google-map.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import {
AfterContentInit,
ChangeDetectionStrategy,
Component,
ContentChildren,
ElementRef,
EventEmitter,
Input,
OnChanges,
OnDestroy,
OnInit,
Output,
QueryList,
} from '@angular/core';
import {BehaviorSubject, combineLatest, Observable, Subject} from 'rxjs';
import {map, shareReplay, take, takeUntil} from 'rxjs/operators';

import {MapMarker} from '../map-marker/index';

interface GoogleMapsWindow extends Window {
google?: typeof google;
}
Expand Down Expand Up @@ -44,9 +49,9 @@ export const DEFAULT_WIDTH = '500px';
@Component({
selector: 'google-map',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<div class="map-container"></div>',
template: '<div class="map-container"></div><ng-content></ng-content>',
})
export class GoogleMap implements OnChanges, OnInit, OnDestroy {
export class GoogleMap implements OnChanges, OnInit, AfterContentInit, OnDestroy {
@Input() height = DEFAULT_HEIGHT;

@Input() width = DEFAULT_WIDTH;
Expand Down Expand Up @@ -172,9 +177,13 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
*/
@Output() zoomChanged = new EventEmitter<void>();

@ContentChildren(MapMarker) _markers: QueryList<MapMarker>;

private _mapEl: HTMLElement;
private _googleMap!: UpdatedGoogleMap;

private _googleMapChanges!: Observable<google.maps.Map>;

private readonly _listeners: google.maps.MapsEventListener[] = [];

private readonly _options = new BehaviorSubject<google.maps.MapOptions>(DEFAULT_OPTIONS);
Expand Down Expand Up @@ -204,13 +213,21 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {

const combinedOptionsChanges = this._combineOptions();

const googleMapChanges = this._initializeMap(combinedOptionsChanges);
googleMapChanges.subscribe((googleMap: google.maps.Map) => {
this._googleMapChanges = this._initializeMap(combinedOptionsChanges);
this._googleMapChanges.subscribe((googleMap: google.maps.Map) => {
this._googleMap = googleMap as UpdatedGoogleMap;

this._initializeEventHandlers();
});

this._watchForOptionsChanges(googleMapChanges, combinedOptionsChanges);
this._watchForOptionsChanges(combinedOptionsChanges);
}

ngAfterContentInit() {
for (const marker of this._markers.toArray()) {
marker._setMap(this._googleMap);
}
this._watchForMarkerChanges();
}

ngOnDestroy() {
Expand Down Expand Up @@ -391,9 +408,8 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
}

private _watchForOptionsChanges(
googleMapChanges: Observable<google.maps.Map>,
optionsChanges: Observable<google.maps.MapOptions>) {
combineLatest(googleMapChanges, optionsChanges)
combineLatest(this._googleMapChanges, optionsChanges)
.pipe(takeUntil(this._destroy))
.subscribe(([googleMap, options]) => {
googleMap.setOptions(options);
Expand Down Expand Up @@ -445,4 +461,14 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
}));
}
}

private _watchForMarkerChanges() {
combineLatest(this._googleMapChanges, this._markers.changes)
.pipe(takeUntil(this._destroy))
.subscribe(([googleMap, markers]) => {
for (let marker of markers) {
marker._setMap(googleMap);
}
});
}
}
Loading

0 comments on commit c8ceae5

Please sign in to comment.