src/app/core/ui/routed-view/routed-view.component.ts

Description

Wrapper component for a primary, full page view that takes parameters from the route and passes these on to normal @Input properties.

This allows to develop functional feature components in a way to easily reuse them for display as a full page view or in a modal dialog.

Extends

AbstractViewComponent

Example

Metadata

Relationships

Used by

No results matching.

Index

Properties

Constructor

constructor()

Properties

component
Type : string
config
Type : any
componentInjector
Type : Injector | undefined
Inherited from AbstractViewComponent
viewContext
Type : ViewComponentContext
Inherited from AbstractViewComponent
import {
  Component,
  DestroyRef,
  Injector,
  ChangeDetectorRef,
  inject,
  ChangeDetectionStrategy,
} from "@angular/core";
import { CommonModule } from "@angular/common";
import { ActivatedRoute } from "@angular/router";
import { combineLatest } from "rxjs";
import { ViewConfig } from "../../config/dynamic-routing/view-config.interface";
import { RouteTarget } from "../../../route-target";
import { DynamicComponentPipe } from "../../config/dynamic-components/dynamic-component.pipe";
import { AbstractViewComponent } from "../abstract-view/abstract-view.component";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";

/**
 * Wrapper component for a primary, full page view
 * that takes parameters from the route and passes these on to normal @Input properties.
 *
 * This allows to develop functional feature components in a way to easily reuse them for display
 * as a full page view or in a modal dialog.
 */
@RouteTarget("RoutedView")
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: "app-routed-view",
  imports: [CommonModule, DynamicComponentPipe],
  templateUrl: "./routed-view.component.html",
})
export class RoutedViewComponent<T = any> extends AbstractViewComponent {
  component: string;
  config: any;

  constructor() {
    const route = inject(ActivatedRoute);
    const injector = inject(Injector);
    const cdr = inject(ChangeDetectorRef);
    const destroyRef = inject(DestroyRef);

    super(injector, false);

    combineLatest([route.data, route.paramMap])
      .pipe(takeUntilDestroyed(destroyRef))
      .subscribe(([data, params]) => {
        const { component, config } = data as {
          component: string;
        } & ViewConfig<T>;
        this.component = component;
        // pass all other config properties to the component as config,
        // then merge in route params so initial params are always applied
        const merged: any = Object.assign({}, config);
        for (const key of params.keys) {
          merged[key] = params.get(key);
        }
        this.config = merged;
        cdr.markForCheck();
      });

    this.viewContext.changes$
      .pipe(takeUntilDestroyed(destroyRef))
      .subscribe(() => cdr.markForCheck());
  }
}
<div class="flex-row flex-wrap">
  <div class="flex-grow">
    <ng-container
      *ngTemplateOutlet="viewContext?.title?.template"
    ></ng-container>
  </div>

  <ng-container
    *ngTemplateOutlet="viewContext?.actions?.template"
  ></ng-container>
</div>

<ng-container
  *ngComponentOutlet="
    component | dynamicComponent | async;
    inputs: config;
    injector: componentInjector
  "
></ng-container>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""