import {NgModule,Component,ElementRef,OnInit,AfterViewChecked,DoCheck,OnDestroy,Input,Output,EventEmitter,IterableDiffers,ChangeDetectorRef,NgZone} from '@angular/core';
import {CommonModule} from '@angular/common';
declare var google: any;
@Component({
selector: 'p-gmap',
template: `
`
})
export class GMap implements AfterViewChecked,DoCheck {
@Input() style: any;
@Input() styleClass: string;
@Input() options: any;
@Input() overlays: any[];
@Output() onMapClick: EventEmitter = new EventEmitter();
@Output() onOverlayClick: EventEmitter = new EventEmitter();
@Output() onOverlayDragStart: EventEmitter = new EventEmitter();
@Output() onOverlayDrag: EventEmitter = new EventEmitter();
@Output() onOverlayDragEnd: EventEmitter = new EventEmitter();
@Output() onMapReady: EventEmitter = new EventEmitter();
@Output() onMapDragEnd: EventEmitter = new EventEmitter();
@Output() onZoomChanged: EventEmitter = new EventEmitter();
differ: any;
map: any;
constructor(public el: ElementRef,differs: IterableDiffers, public cd: ChangeDetectorRef, public zone:NgZone) {
this.differ = differs.find([]).create(null);
}
ngAfterViewChecked() {
if(!this.map && this.el.nativeElement.offsetParent) {
this.initialize();
}
}
initialize() {
this.map = new google.maps.Map(this.el.nativeElement.children[0], this.options);
this.onMapReady.emit({
map: this.map
});
if(this.overlays) {
for(let overlay of this.overlays) {
overlay.setMap(this.map);
this.bindOverlayEvents(overlay);
}
}
this.map.addListener('click', (event) => {
this.zone.run(() => {
this.onMapClick.emit(event);
});
});
this.map.addListener('dragend', (event) => {
this.zone.run(() => {
this.onMapDragEnd.emit(event);
});
});
this.map.addListener('zoom_changed', (event) => {
this.zone.run(() => {
this.onZoomChanged.emit(event);
});
});
}
bindOverlayEvents(overlay: any) {
overlay.addListener('click', (event) => {
this.zone.run(() => {
this.onOverlayClick.emit({
originalEvent: event,
'overlay': overlay,
map: this.map
});
});
});
if(overlay.getDraggable()) {
this.bindDragEvents(overlay);
}
}
ngDoCheck() {
let changes = this.differ.diff(this.overlays);
if(changes && this.map) {
changes.forEachRemovedItem((record) => {
google.maps.event.clearInstanceListeners(record.item);
record.item.setMap(null);
});
changes.forEachAddedItem((record) => {
record.item.setMap(this.map);
record.item.addListener('click', (event) => {
this.zone.run(() => {
this.onOverlayClick.emit({
originalEvent: event,
overlay: record.item,
map: this.map
});
});
});
if(record.item.getDraggable()) {
this.bindDragEvents(record.item);
}
});
}
}
bindDragEvents(overlay) {
overlay.addListener('dragstart', (event) => {
this.zone.run(() => {
this.onOverlayDragStart.emit({
originalEvent: event,
overlay: overlay,
map: this.map
});
});
});
overlay.addListener('drag', (event) => {
this.zone.run(() => {
this.onOverlayDrag.emit({
originalEvent: event,
overlay: overlay,
map: this.map
});
});
});
overlay.addListener('dragend', (event) => {
this.zone.run(() => {
this.onOverlayDragEnd.emit({
originalEvent: event,
overlay: overlay,
map: this.map
});
});
});
}
getMap() {
return this.map;
}
}
@NgModule({
imports: [CommonModule],
exports: [GMap],
declarations: [GMap]
})
export class GMapModule { }