Skip to content

🤖 A collection of tools to make your Angular views more modular, scalable, and maintainable

License

Notifications You must be signed in to change notification settings

ngneat/overview

Repository files navigation


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
6.x >= 17
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 thedynamicViewstructural 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],
})
exportclassErrorComponent{
@Input()view:Content|undefined;
}

You can also pass acontextor aninjectorasinputsto the directive:

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

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

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

If you passcontextto a component and the value can be accessed via theinjectViewContextfunction:

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

interfaceContext{
title:string;
}

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

injectViewContextreturns 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 thisarticle.

Use theteleportOutletdirective to define a newoutlet.Anoutletis 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],
})
exportclassFooComponent{}

Use theteleportTodirective toteleportthe view to a specificoutlet:

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

@Component({
template:`
<section *teleportTo= "someId" >
{{ value }}
</section>
`,
standalone:true,
imports:[TeleportDirective],
})
exportclassBarComponent{
value='...';
}

ViewService

TheViewServiceprovidesfacademethods to create modular views in Angular. It's been used in various projects likehot-toast,andhelipopper.

createComponent

ThecreateComponentmethod takes aComponent,and returns an instance ofCompRef:

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

@Injectable()
classToastService{
privateviewService=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 Angularcomponenttemplate in a third-party library that takes a native DOM element or a string. In this case, we can use thegetRawContentor thegetElementmethod, respectively.

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

@Directive()
classChartDirective{
privateviewService=inject(ViewService);

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

constcontent=ref.getRawContent();

ref.destroy();

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

createComponentOptions

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

createTemplate

ThecreateTemplatemethod takes aTemplateRef,and returns an instance ofViewRef.

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

createView

ThecreateViewmethod takes aComponent,aTemplateRefor astring,and creates aView:

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

@Injectable()
classToastService{
privateviewService=inject(ViewService);

createToast(content:Content){
constref=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 theall-contributorsspecification. Contributions of any kind welcome!

Icons made byFreepikfromflaticon

About

🤖 A collection of tools to make your Angular views more modular, scalable, and maintainable

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published