File

src/app/component/popover/popover.service.ts

Index

Properties
Methods

Constructor

constructor(_overlay: Overlay, _viewContainerRef: ViewContainerRef)
Parameters :
Name Type Optional
_overlay Overlay No
_viewContainerRef ViewContainerRef No

Methods

Private _attachContainer
_attachContainer(overlayRef)
Parameters :
Name Optional
overlayRef No
Returns : any
Private _createOverlay
_createOverlay(config?)
Parameters :
Name Optional
config Yes
Returns : OverlayRef
Private _getPosition
_getPosition()
Returns : any
afterOpened
afterOpened()
Returns : void
anchor
anchor(popover: PopoverComponent, viewContainerRef: ViewContainerRef, elementRef: ElementRef)
Parameters :
Name Type Optional
popover PopoverComponent No
viewContainerRef ViewContainerRef No
elementRef ElementRef No
Returns : void
close
close()
Returns : void
dismiss
dismiss()
Returns : void
open
open()
Returns : any

Properties

Private Readonly _afterClosed
Default value : new Subject<void>()
Private Readonly _afterOpened
Default value : new Subject<void>()
Private _elementRef
Type : ElementRef
Private _openedRef
Private _overlayRef
Type : OverlayRef | null
Default value : null
Private _popover
Type : PopoverComponent
import { Injectable, ViewContainerRef, ElementRef } from '@angular/core';
import { TemplatePortal } from '@angular/cdk/portal';
import {
  Overlay,
  OverlayRef,
  OverlayConfig,
  HorizontalConnectionPos,
  VerticalConnectionPos
} from '@angular/cdk/overlay';
import { ESCAPE } from '@angular/cdk/keycodes';
import { filter } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { PopoverComponent } from './popover.component';
import { PopoverRef } from './popover.ref';

@Injectable({
  providedIn: 'root'
})
export class PopoverService {
  private readonly _afterOpened = new Subject<void>();
  private readonly _afterClosed = new Subject<void>();

  private _popover: PopoverComponent;
  private _elementRef: ElementRef;
  private _overlayRef: OverlayRef | null = null;
  private _openedRef;

  constructor(
    private _overlay: Overlay,
    private _viewContainerRef: ViewContainerRef
  ) {}

  open() {
    this._overlayRef = this._createOverlay();
    const container = this._attachContainer(this._overlayRef);
    const popoverRef = new PopoverRef(container, this._overlayRef);

    popoverRef.instance = container.instance;

    this._overlayRef.backdropClick().subscribe(() => this.dismiss());
    this._overlayRef
      .keydownEvents()
      .pipe(filter(event => event.keyCode === ESCAPE))
      .subscribe(() => this.dismiss());

    this._openedRef = popoverRef;

    return popoverRef;
  }

  close() {
    if (this._openedRef) {
      this._openedRef.dismissWithAction();
      this._overlayRef.detach();
    }
  }

  dismiss() {
    if (this._openedRef) {
      this._openedRef.dismissWithAction();
      this._overlayRef.dispose();
    }
  }

  anchor(
    popover: PopoverComponent,
    viewContainerRef: ViewContainerRef,
    elementRef: ElementRef
  ) {
    this._popover = popover;
    this._viewContainerRef = viewContainerRef;
    this._elementRef = elementRef;

    this._afterOpened.asObservable().subscribe(() => {
      this.open();
    });
  }

  afterOpened() {
    this._afterOpened.next();
    this._afterOpened.complete();
  }

  private _attachContainer(overlayRef) {
    const containerPortal = new TemplatePortal(
      this._popover.templateRef,
      this._viewContainerRef
    );

    const containerRef = overlayRef.attach(containerPortal);

    return containerRef;
  }

  private _createOverlay(config?): OverlayRef {
    const overlayConfig = new OverlayConfig({
      positionStrategy: this._getPosition(),
      backdropClass: 'cdk-overlay-transparent-backdrop',
      hasBackdrop: true
    });

    return this._overlay.create(overlayConfig);
  }

  private _getPosition() {
    let [originX, originFallbackX]: HorizontalConnectionPos[] = [
      'start',
      'end'
    ];
    let [overlayY, overlayFallbackY]: VerticalConnectionPos[] = [
      'top',
      'bottom'
    ];

    let [originY, originFallbackY] = [overlayY, overlayFallbackY];
    let [overlayX, overlayFallbackX] = [originX, originFallbackX];
    let offsetY = 8;

    const strategy = this._overlay
      .position()
      .flexibleConnectedTo(this._elementRef)
      .withPositions([
        {
          originX: 'start',
          originY: 'bottom',
          overlayX: 'start',
          overlayY: 'top'
        },
        {
          originX: 'start',
          originY: 'top',
          overlayX: 'start',
          overlayY: 'bottom'
        }
      ]);

    return strategy;
  }
}

result-matching ""

    No results matching ""