Skip to content

Commit

Permalink
feat(popup): add open event (from mapbox-gl v0.45.0)
Browse files Browse the repository at this point in the history
Also refactor a bit PopupComponent
  • Loading branch information
Wykks committed May 11, 2018
1 parent 339562c commit c417d82
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 26 deletions.
50 changes: 48 additions & 2 deletions src/app/lib/map/map.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ export interface SetupLayer {
};
}

export interface SetupPopup {
popupOptions: MapboxGl.PopupOptions;
popupEvents: {
open: EventEmitter<void>;
close: EventEmitter<void>;
};
}

export type AllSource = MapboxGl.VectorSource |
MapboxGl.RasterSource |
MapboxGl.GeoJSONSource |
Expand Down Expand Up @@ -249,16 +257,54 @@ export class MapService {
this.markersToRemove.push(marker);
}

addPopup(popup: MapboxGl.Popup) {
createPopup(popup: SetupPopup, element: Node) {
return this.zone.runOutsideAngular(() => {
Object.keys(popup.popupOptions)
.forEach((key) =>
(<any>popup.popupOptions)[key] === undefined && delete (<any>popup.popupOptions)[key]);
const popupInstance = new MapboxGl.Popup(popup.popupOptions);
popupInstance.setDOMContent(element);
if (popup.popupEvents.close.observers.length) {
popupInstance.on('close', () => {
this.zone.run(() => {
popup.popupEvents.close.emit();
});
});
}
if (popup.popupEvents.open.observers.length) {
popupInstance.on('open', () => {
this.zone.run(() => {
popup.popupEvents.open.emit();
});
});
}
return popupInstance;
});
}

addPopupToMap(popup: MapboxGl.Popup, lngLat: MapboxGl.LngLatLike) {
return this.zone.runOutsideAngular(() => {
popup.setLngLat(lngLat);
popup.addTo(this.mapInstance);
});
}

removePopup(popup: MapboxGl.Popup) {
addPopupToMarker(marker: MapboxGl.Marker, popup: MapboxGl.Popup) {
return this.zone.runOutsideAngular(() => {
marker.setPopup(popup);
});
}

removePopupFromMap(popup: MapboxGl.Popup) {
this.popupsToRemove.push(popup);
}

removePopupFromMarker(marker: MapboxGl.Marker) {
return this.zone.runOutsideAngular(() => {
marker.setPopup(undefined);
});
}

addControl(control: MapboxGl.Control | MapboxGl.IControl, position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left') {
return this.zone.runOutsideAngular(() => {
this.mapInstance.addControl(<any>control, position);
Expand Down
57 changes: 33 additions & 24 deletions src/app/lib/popup/popup.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class PopupComponent implements OnChanges, OnDestroy, AfterViewInit, OnIn
@Input() marker?: MarkerComponent;

@Output() close = new EventEmitter<void>();
@Output() open = new EventEmitter<void>();

@ViewChild('content') content: ElementRef;

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

ngOnChanges(changes: SimpleChanges) {
if (changes.lngLat && !changes.lngLat.isFirstChange()) {
this.MapService.removePopup(this.popupInstance!);
this.MapService.removePopupFromMap(this.popupInstance!);
const popupInstanceTmp = this.createPopup();
this.MapService.addPopup(popupInstanceTmp);
this.MapService.addPopupToMap(popupInstanceTmp, changes.lngLat.currentValue);
this.popupInstance = popupInstanceTmp;
}
if (changes.marker && !changes.marker.isFirstChange()) {
const previousMarker: MarkerComponent = changes.marker.previousValue;
if (previousMarker.markerInstance) {
previousMarker.markerInstance.setPopup(undefined);
this.MapService.removePopupFromMarker(previousMarker.markerInstance);
}
if (this.marker && this.marker.markerInstance) {
this.marker.markerInstance.setPopup(this.popupInstance);
if (this.marker && this.marker.markerInstance && this.popupInstance) {
this.MapService.addPopupToMarker(this.marker.markerInstance, this.popupInstance);
}
}
}

ngAfterViewInit() {
this.popupInstance = this.createPopup();
this.addPopup(this.popupInstance);
}

ngOnDestroy() {
this.MapService.removePopup(this.popupInstance!);
if (this.popupInstance) {
if (this.lngLat) {
this.MapService.removePopupFromMap(this.popupInstance);
} else if (this.marker && this.marker.markerInstance) {
this.MapService.removePopupFromMarker(this.marker.markerInstance);
}
}
this.popupInstance = undefined;
}

private createPopup() {
const options = {
closeButton: this.closeButton,
closeOnClick: this.closeOnClick,
anchor: this.anchor,
offset: this.offset
};
Object.keys(options)
.forEach((key) =>
(<any>options)[key] === undefined && delete (<any>options)[key]);
const popupInstance = new Popup(options);
popupInstance.once('close', () => {
this.close.emit();
});
popupInstance.setDOMContent(this.content.nativeElement);
return this.MapService.createPopup({
popupOptions: {
closeButton: this.closeButton,
closeOnClick: this.closeOnClick,
anchor: this.anchor,
offset: this.offset
},
popupEvents: {
open: this.open,
close: this.close
}
}, this.content.nativeElement);
}

private addPopup(popup: Popup) {
this.MapService.mapCreated$.subscribe(() => {
if (this.lngLat) {
popupInstance.setLngLat(this.lngLat);
this.MapService.addPopup(popupInstance);
this.MapService.addPopupToMap(popup, this.lngLat);
} else if (this.marker && this.marker.markerInstance) {
this.marker.markerInstance.setPopup(popupInstance);
this.MapService.addPopupToMarker(this.marker.markerInstance, popup);
} else {
throw new Error('mgl-popup need either lngLat or marker to be set');
}
});
return popupInstance;
}
}

0 comments on commit c417d82

Please sign in to comment.