@ngneat/overview
TypeScript icon, indicating that this package has built-in type declarations

6.0.0 • Public • Published


npm MIT Commitizen friendly PRs styled with prettier All Contributors ngneat spectator

Overview - The Template for Success in Template Management

Compatibility with Angular Versions

@ngneat/overview Angular
5.x >= 16
4.x >= 14 < 16
3.x >= 13 < 14
2.x >= 11 < 13

Installation

npm i @ngneat/overview
yarn add @ngneat/overview

Table of Contents

DynamicView

Use the dynamicView structural directive to render a component, a template, HTML, or default template dynamically.

Let’s say we build a generic error component. What we want is to give our consumers the flexibly to create it by using one of three options:

  • They can choose to use the default template
  • They can choose to use their own text which can be static or dynamic
  • They can choose to pass their own template or component
import { DynamicViewModule, Content } from '@ngneat/overview';

@Component({
  template: `
    <div *dynamicView="view">
      Default view
    </div>
  `,
  standalone: true,
  imports: [DynamicViewModule]
})
export class ErrorComponent {
  @Input() view: Content | undefined;
}

You can also pass a context or an injector as inputs to the directive:

<h5>Component</h5>
<ng-container *dynamicView="component; 
    injector: myInjector; 
    context: { $implicit: 'my title' }"/>

<h5>Template</h5>
<ng-template #tpl let-title>
  <b>{{ title }}</b>
</ng-template>

<ng-container *dynamicView="tpl; context: { $implicit: 'my title' }"/>

If you pass context to a component and the value can be accessed via the injectViewContext function:

import { injectViewContext } from '@ngneat/overview';

interface Context {
  title: string;
}

@Component({
  template: `<div>{{ context().title }}</div>`,
  standalone: true
})
export class MyDynamicComponent {
    context: Signal<Context> = injectViewContext<Context>();
}

injectViewContext returns a readonly signal with the view's context object.

Teleporting

Teleporting means rendering a view at a different location from its declaration. There are two cases it might be helpful:

  • Avoid prop drilling to a nested component.
  • Rendering a view at another place in the DOM while keeping its context where it’s defined.

You can read more about this approach in this article.

Use the teleportOutlet directive to define a new outlet. An outlet is an anchor where the view will be projected as a sibling.

import { TeleportModule } from '@ngneat/overview';

@Component({ 
  template: `
    <div class="flex">
      <ng-container teleportOutlet="someId"/>
    </div>
  `,
  standalone: true,
  imports: [TeleportModule]
})
export class FooComponent {}

Use the teleportTo directive to teleport the view to a specific outlet:

import { TeleportModule } from '@ngneat/overview';

@Component({ 
  template: `
   <section *teleportTo="someId">
      {{ value }}
    </section>
  `,
  standalone: true,
  imports: [TeleportModule]
})
export class BarComponent {
  value = '...'
}

ViewService

The ViewService provides facade methods to create modular views in Angular. It's been used in various projects like hot-toast, and helipopper.

createComponent

The createComponent method takes a Component, and returns an instance of CompRef:

import { ViewService, CompRef } from '@ngneat/overview';

@Injectable()
class ToastService {
  private viewService = inject(ViewService);
  componentRef: CompRef;

  init() {
   this.componentRef = this.viewService
      .createComponent(HotToastContainerComponent)
      .setInput('defaultConfig', defaultConfig)
      .appendTo(document.body);
  }
}

There are cases where we want to use an Angular component template in a third-party library that takes a native DOM element or a string. In this case, we can use the getRawContent or the getElement method, respectively.

import {ViewService} from '@ngneat/overview';

@Directive()
class ChartDirective {
    private viewService = inject(ViewService);

    createChart(color: string) {
        const ref = this.viewService
            .createComponent(FooTooltip)
            .setInput('color', color)
            .detectChanges(document.body);

        const content = ref.getRawContent();

        ref.destroy();

        Highcharts.chart('container', {
            tooltip: {
                formatter: function () {
                    return content;
                },
                useHTML: true
            },
        });
    }
}

createComponent Options

createComponent<Comp, Context>(component: Type<Comp>, {
  injector?: Injector,
  environmentInjector?: EnvironmentInjector,
  context?: Context,
  vcr?: ViewContainerRef,
})

createTemplate

The createTemplate method takes a TemplateRef, and returns an instance of ViewRef.

createTemplate<Context>(tpl: TemplateRef<Context>, {
  context?: Context,
  vcr?: ViewContainerRef,
  injector?: Injector,
})

createView

The createView method takes a Component, a TemplateRef or a string, and creates a View:

import { ViewService, Content } from '@ngneat/overview';

@Injectable()
class ToastService {
  private viewService = inject(ViewService);

  createToast(content: Content) {
    const ref = this.viewService.createView(content);
    document.body.appendChild(ref.getElement());
  }
}

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Netanel Basal

💻 🤔

Dharmen Shah

🖋 📖

This project follows the all-contributors specification. Contributions of any kind welcome!

Icons made by Freepik from www.flaticon.com

Package Sidebar

Install

npm i @ngneat/overview

Weekly Downloads

16,643

Version

6.0.0

License

MIT

Unpacked Size

114 kB

Total Files

28

Last publish

Collaborators

  • netanel-ngneat
  • itayod
  • shahar.kazaz