Skip to content

Commit c417d82

Browse files
author
Wykks
committed
feat(popup): add open event (from mapbox-gl v0.45.0)
Also refactor a bit PopupComponent
1 parent 339562c commit c417d82

File tree

2 files changed

+81
-26
lines changed

2 files changed

+81
-26
lines changed

src/app/lib/map/map.service.ts

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ export interface SetupLayer {
3131
};
3232
}
3333

34+
export interface SetupPopup {
35+
popupOptions: MapboxGl.PopupOptions;
36+
popupEvents: {
37+
open: EventEmitter<void>;
38+
close: EventEmitter<void>;
39+
};
40+
}
41+
3442
export type AllSource = MapboxGl.VectorSource |
3543
MapboxGl.RasterSource |
3644
MapboxGl.GeoJSONSource |
@@ -249,16 +257,54 @@ export class MapService {
249257
this.markersToRemove.push(marker);
250258
}
251259

252-
addPopup(popup: MapboxGl.Popup) {
260+
createPopup(popup: SetupPopup, element: Node) {
261+
return this.zone.runOutsideAngular(() => {
262+
Object.keys(popup.popupOptions)
263+
.forEach((key) =>
264+
(<any>popup.popupOptions)[key] === undefined && delete (<any>popup.popupOptions)[key]);
265+
const popupInstance = new MapboxGl.Popup(popup.popupOptions);
266+
popupInstance.setDOMContent(element);
267+
if (popup.popupEvents.close.observers.length) {
268+
popupInstance.on('close', () => {
269+
this.zone.run(() => {
270+
popup.popupEvents.close.emit();
271+
});
272+
});
273+
}
274+
if (popup.popupEvents.open.observers.length) {
275+
popupInstance.on('open', () => {
276+
this.zone.run(() => {
277+
popup.popupEvents.open.emit();
278+
});
279+
});
280+
}
281+
return popupInstance;
282+
});
283+
}
284+
285+
addPopupToMap(popup: MapboxGl.Popup, lngLat: MapboxGl.LngLatLike) {
253286
return this.zone.runOutsideAngular(() => {
287+
popup.setLngLat(lngLat);
254288
popup.addTo(this.mapInstance);
255289
});
256290
}
257291

258-
removePopup(popup: MapboxGl.Popup) {
292+
addPopupToMarker(marker: MapboxGl.Marker, popup: MapboxGl.Popup) {
293+
return this.zone.runOutsideAngular(() => {
294+
marker.setPopup(popup);
295+
});
296+
}
297+
298+
removePopupFromMap(popup: MapboxGl.Popup) {
259299
this.popupsToRemove.push(popup);
260300
}
261301

302+
removePopupFromMarker(marker: MapboxGl.Marker) {
303+
return this.zone.runOutsideAngular(() => {
304+
marker.setPopup(undefined);
305+
});
306+
}
307+
262308
addControl(control: MapboxGl.Control | MapboxGl.IControl, position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left') {
263309
return this.zone.runOutsideAngular(() => {
264310
this.mapInstance.addControl(<any>control, position);

src/app/lib/popup/popup.component.ts

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class PopupComponent implements OnChanges, OnDestroy, AfterViewInit, OnIn
3333
@Input() marker?: MarkerComponent;
3434

3535
@Output() close = new EventEmitter<void>();
36+
@Output() open = new EventEmitter<void>();
3637

3738
@ViewChild('content') content: ElementRef;
3839

@@ -50,54 +51,62 @@ export class PopupComponent implements OnChanges, OnDestroy, AfterViewInit, OnIn
5051

5152
ngOnChanges(changes: SimpleChanges) {
5253
if (changes.lngLat && !changes.lngLat.isFirstChange()) {
53-
this.MapService.removePopup(this.popupInstance!);
54+
this.MapService.removePopupFromMap(this.popupInstance!);
5455
const popupInstanceTmp = this.createPopup();
55-
this.MapService.addPopup(popupInstanceTmp);
56+
this.MapService.addPopupToMap(popupInstanceTmp, changes.lngLat.currentValue);
5657
this.popupInstance = popupInstanceTmp;
5758
}
5859
if (changes.marker && !changes.marker.isFirstChange()) {
5960
const previousMarker: MarkerComponent = changes.marker.previousValue;
6061
if (previousMarker.markerInstance) {
61-
previousMarker.markerInstance.setPopup(undefined);
62+
this.MapService.removePopupFromMarker(previousMarker.markerInstance);
6263
}
63-
if (this.marker && this.marker.markerInstance) {
64-
this.marker.markerInstance.setPopup(this.popupInstance);
64+
if (this.marker && this.marker.markerInstance && this.popupInstance) {
65+
this.MapService.addPopupToMarker(this.marker.markerInstance, this.popupInstance);
6566
}
6667
}
6768
}
6869

6970
ngAfterViewInit() {
7071
this.popupInstance = this.createPopup();
72+
this.addPopup(this.popupInstance);
7173
}
7274

7375
ngOnDestroy() {
74-
this.MapService.removePopup(this.popupInstance!);
76+
if (this.popupInstance) {
77+
if (this.lngLat) {
78+
this.MapService.removePopupFromMap(this.popupInstance);
79+
} else if (this.marker && this.marker.markerInstance) {
80+
this.MapService.removePopupFromMarker(this.marker.markerInstance);
81+
}
82+
}
7583
this.popupInstance = undefined;
7684
}
7785

7886
private createPopup() {
79-
const options = {
80-
closeButton: this.closeButton,
81-
closeOnClick: this.closeOnClick,
82-
anchor: this.anchor,
83-
offset: this.offset
84-
};
85-
Object.keys(options)
86-
.forEach((key) =>
87-
(<any>options)[key] === undefined && delete (<any>options)[key]);
88-
const popupInstance = new Popup(options);
89-
popupInstance.once('close', () => {
90-
this.close.emit();
91-
});
92-
popupInstance.setDOMContent(this.content.nativeElement);
87+
return this.MapService.createPopup({
88+
popupOptions: {
89+
closeButton: this.closeButton,
90+
closeOnClick: this.closeOnClick,
91+
anchor: this.anchor,
92+
offset: this.offset
93+
},
94+
popupEvents: {
95+
open: this.open,
96+
close: this.close
97+
}
98+
}, this.content.nativeElement);
99+
}
100+
101+
private addPopup(popup: Popup) {
93102
this.MapService.mapCreated$.subscribe(() => {
94103
if (this.lngLat) {
95-
popupInstance.setLngLat(this.lngLat);
96-
this.MapService.addPopup(popupInstance);
104+
this.MapService.addPopupToMap(popup, this.lngLat);
97105
} else if (this.marker && this.marker.markerInstance) {
98-
this.marker.markerInstance.setPopup(popupInstance);
106+
this.MapService.addPopupToMarker(this.marker.markerInstance, popup);
107+
} else {
108+
throw new Error('mgl-popup need either lngLat or marker to be set');
99109
}
100110
});
101-
return popupInstance;
102111
}
103112
}

0 commit comments

Comments
 (0)