File

overlays/modules/info-window/directive/google-maps-info-window.directive.ts

Description

Adds an info window to the containing map.

Must be placed inside a <bs-google-map/> element.

Implements

AfterContentChecked

Metadata

Index

Methods
Inputs
Outputs

Inputs

animation
Type : google.maps.Animation
attachedTo
Type : IGoogleMapsMouseEventsEmitter
closeAfter
Type : number
disableAutoPan
Type : boolean
maxWidth
Type : number
options
Type : google.maps.InfoWindowOptions
pixelOffset
Type : google.maps.Size
position
Type : BoundsLike
trigger
Type : InfoWindowTrigger
zIndex
Type : number

Outputs

closeClick
Type : Observable<IGoogleMapsEventData>

Fired when the infoWindow's animation property changes.

contentChanged
Type : Observable<IGoogleMapsEventData>

Fired when the infoWindow icon was clicked.

domReady
Type : Observable<IGoogleMapsEventData>

Fired for a rightclick on the infoWindow.

positionChanged
Type : Observable<IGoogleMapsEventData>

Fired when the infoWindow's clickable property changes.

zIndexChanged
Type : Observable<IGoogleMapsEventData>

Fired when the infoWindow icon was double clicked.

Methods

ngAfterContentChecked
ngAfterContentChecked()

Reviews changes to the content placed inside and updates the window's content with any changes.

Observing content changes could be achieved with ContentObserver from the cdk package. However, I chose not to rely on another dependency, as this is specifically used in this directive. Moreover, it doesn't seem likely that info window content will change often, so it didn't seem to matter. If this causes a performance issue in the future, consider ContentObserver.

Returns: void
ngOnDestroy
ngOnDestroy()
Returns: void
import { Observable } from 'rxjs';
import { Input, Output, Directive, AfterContentChecked } from '@angular/core';

import { GoogleMapsComponentBase, IGoogleMapsEventData, Hook, BoundsLike, IGoogleMapsMouseEventsEmitter } from '@bespunky/angular-google-maps/core';
import { GoogleMapsInfoWindowFactoryProvider, NativeGoogleMapsInfoWindowFactoryProvider                 } from '../google-maps-info-window-factory.provider';
import { IGoogleMapsInfoWindow, InfoWindowTrigger                                                       } from '../i-google-maps-info-window';

/**
 * Adds an info window to the containing map.
 * 
 * Must be placed inside a `<bs-google-map/>` element.
 *
 * @export
 * @class GoogleMapsInfoWindowDirective
 * @extends {GoogleMapsComponentBase<IGoogleMapsInfoWindow>}
 * @implements {AfterContentChecked}
 */
@Directive({
    selector : 'bs-google-maps-info-window, [bsGoogleMapsInfoWindow]',
    exportAs : 'infoWindow',
    providers: [GoogleMapsInfoWindowFactoryProvider, NativeGoogleMapsInfoWindowFactoryProvider]
})
export class GoogleMapsInfoWindowDirective extends GoogleMapsComponentBase<IGoogleMapsInfoWindow> implements AfterContentChecked
{
    @Input() public animation?     : google.maps.Animation;
    @Input() public position?      : BoundsLike;
    @Input() public zIndex?        : number;
    @Input() public options?       : google.maps.InfoWindowOptions;
    @Input() public disableAutoPan?: boolean;
    @Input() public maxWidth?      : number;
    @Input() public pixelOffset?   : google.maps.Size;
    
    @Input() public trigger?   : InfoWindowTrigger ;
    @Input() public closeAfter?: number;
    @Input() public attachedTo?: IGoogleMapsMouseEventsEmitter;

    /** Fired when the infoWindow's animation property changes. */
    @Hook('closeclick')       @Output() public closeClick: Observable<IGoogleMapsEventData>;
    /** Fired when the infoWindow icon was clicked. */
    @Hook('content_changed')  @Output() public contentChanged: Observable<IGoogleMapsEventData>;
    /** Fired for a rightclick on the infoWindow. */
    @Hook('domready')         @Output() public domReady: Observable<IGoogleMapsEventData>;
    /** Fired when the infoWindow's clickable property changes. */
    @Hook('position_changed') @Output() public positionChanged: Observable<IGoogleMapsEventData>;
    /** Fired when the infoWindow icon was double clicked. */
    @Hook('zindex_changed')   @Output() public zIndexChanged: Observable<IGoogleMapsEventData>;

    /**
     * Reviews changes to the content placed inside <bs-google-maps-info-window> and updates the window's content with any changes.
     *
     * Observing content changes could be achieved with `ContentObserver` from the `cdk` package. However, I chose not to rely on another
     * dependency, as this is specifically used in this directive. Moreover, it doesn't seem likely that info window content will change
     * often, so it didn't seem to matter.
     * If this causes a performance issue in the future, consider `ContentObserver`.
     */
    ngAfterContentChecked()
    {
        // Build a template for the updated content
        const current = this.buildContentTemplate();
        // Get the last set content template so it could be compared to the current one
        const last    = this.wrapper.getContent() as string;

        // If the content has changed (due to an *ngFor, interpolation or whatever), refresh the info window
        if (current !== last) this.wrapper.setContent(current);
    }

    ngOnDestroy()
    {
        this.wrapper.clearAttachedTo();
        
        super.ngOnDestroy();
    }

    private buildContentTemplate(): string
    {
        const element      = this.element.nativeElement as HTMLElement;
        const childrenHtml = Array.from(element.children).map(element => element.outerHTML).join('');

        return `<div class="google-maps-info-window">${childrenHtml}</div>`;
    }
}

results matching ""

    No results matching ""