File

src/lib/window-content/window-content.component.ts

Implements

AfterViewInit OnInit

Metadata

Index

Properties

Constructor

constructor(context: any, windowRef: WindowRef, injector: Injector, viewContainerRef: ViewContainerRef, loadingIndicatorService: LoadingIndicatorService)
Parameters :
Name Type Optional
context any No
windowRef WindowRef No
injector Injector No
viewContainerRef ViewContainerRef No
loadingIndicatorService LoadingIndicatorService No

Properties

Public context
Type : WindowContainerContext<any>
Public portal
Type : Portal<any> | null
Default value : null
Public portalOutlet
Type : CdkPortalOutlet
Decorators :
@ViewChild(CdkPortalOutlet)
import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  ComponentRef,
  Inject,
  Injector,
  isDevMode,
  OnInit,
  ViewChild,
  ViewContainerRef,
} from '@angular/core';
import {
  RXAP_WINDOW_CONTAINER_CONTEXT,
  RXAP_WINDOW_REF,
} from '../tokens';
import { WindowContainerContext } from '../window-context';
import {
  CdkPortalOutlet,
  ComponentPortal,
  Portal,
  PortalModule,
  TemplatePortal,
} from '@angular/cdk/portal';
import type { WindowRef } from '../window-ref';
import {
  catchError,
  delay,
  filter,
  startWith,
  take,
  tap,
  timeout,
} from 'rxjs/operators';
import {
  isObservable,
  throwError,
  TimeoutError,
} from 'rxjs';
import { LoadingIndicatorService } from '@rxap/services';
import { isDefined } from '@rxap/rxjs';

@Component({
    selector: 'rxap-window-content',
    templateUrl: './window-content.component.html',
    styleUrls: ['./window-content.component.scss'],
    changeDetection: ChangeDetectionStrategy.Default,
    imports: [PortalModule]
})
export class WindowContentComponent implements AfterViewInit, OnInit {

  public context: WindowContainerContext<any>;

  public portal: Portal<any> | null = null;

  @ViewChild(CdkPortalOutlet)
  public portalOutlet!: CdkPortalOutlet;

  constructor(
    @Inject(RXAP_WINDOW_CONTAINER_CONTEXT)
      context: any,
    @Inject(RXAP_WINDOW_REF)
    private readonly windowRef: WindowRef,
    private readonly injector: Injector,
    private readonly viewContainerRef: ViewContainerRef,
    private readonly loadingIndicatorService: LoadingIndicatorService,
  ) {
    this.context = context;
  }

  public ngOnInit() {
    if (this.context.template) {
      this.portal = new TemplatePortal(this.context.template, this.viewContainerRef);
    } else if (this.context.component) {
      this.portal = new ComponentPortal<any>(this.context.component, this.viewContainerRef, this.injector);
    }
  }

  public ngAfterViewInit() {
    this.portalOutlet.attached.pipe(
      startWith(this.portalOutlet.attachedRef),
      isDefined(),
      take(1),
      tap(attachedRef => this.windowRef.setAttachedRef(attachedRef)),
      tap(attachedRef => {
        const promise: Promise<any>[] = [];
        if (attachedRef instanceof ComponentRef) {
          attachedRef.changeDetectorRef.detectChanges();
          const loading$ = attachedRef.instance.loading$;
          if (loading$ && isObservable(loading$)) {
            if (isDevMode()) {
              console.warn('The component has a loading indicator member');
            }
            this.loadingIndicatorService.attachLoading(loading$);
            promise.push(loading$.pipe(
              filter(Boolean),
              take(1),
              delay(100),
              tap(() => attachedRef.changeDetectorRef.detectChanges()),
            ).toPromise());
          } else {
            this.loadingIndicatorService.disable();
          }
        } else {
          this.loadingIndicatorService.disable();
        }
        return Promise.all(promise);
      }),
      timeout(10000),
      catchError(error => {

        if (error instanceof TimeoutError) {
          if (isDevMode()) {
            console.warn('The window content never resolved the attached ref');
          }
        }

        return throwError(error);
      }),
    ).subscribe();
  }

}
<div class="p-4">
  <ng-template [cdkPortalOutlet]="portal"></ng-template>
</div>

./window-content.component.scss

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""