Overview - The Template for Success in Template Management
@ngneat/overview | Angular |
---|---|
6.x | >= 17 |
5.x | >= 16 |
4.x | >= 14 < 16 |
3.x | >= 13 < 14 |
2.x | >= 11 < 13 |
npm i @ngneat/overview yarn add @ngneat/overview
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 { DynamicViewDirective, Content } from '@ngneat/overview'; @Component({ template: ` <div *dynamicView="view">Default view</div> `, standalone: true, imports: [DynamicViewDirective], }) 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 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 { TeleportOutletDirective } from '@ngneat/overview'; @Component({ template: ` <div class="flex"> <ng-container teleportOutlet="someId"/> </div> `, standalone: true, imports: [TeleportOutletDirective], }) export class FooComponent {}
Use the teleportTo
directive to teleport
the view to a specific outlet
:
import { TeleportDirective } from '@ngneat/overview'; @Component({ template: ` <section *teleportTo="someId"> {{ value }} </section> `, standalone: true, imports: [TeleportDirective], }) export class BarComponent { value = '...'; }
The ViewService
provides facade
methods to create modular views in Angular. It's been used in various projects like hot-toast, and helipopper.
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<Comp, Context>(component: Type<Comp>, { injector?: Injector, environmentInjector?: EnvironmentInjector, context?: Context, vcr?: ViewContainerRef, })
The createTemplate
method takes a TemplateRef
, and returns an instance of ViewRef
.
createTemplate<Context>(tpl: TemplateRef<Context>, { context?: Context, vcr?: ViewContainerRef, injector?: Injector, })
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()); } }
Thanks goes to these wonderful people (emoji key):
Netanel Basal 💻 🤔 | Dharmen Shah 🖋 📖 |
This project follows the all-contributors specification. Contributions of any kind welcome!