Skip to content

ngneat/overview

main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
e2e
December 16, 2020 17:31
December 16, 2020 17:42
src
January 22, 2023 14:17
December 16, 2020 17:31
February 9, 2023 14:57
December 16, 2020 17:42
December 16, 2020 17:42
December 16, 2020 17:42
December 16, 2020 17:42
December 16, 2020 17:42
December 16, 2020 17:42
December 16, 2020 17:31
December 16, 2020 17:42
December 16, 2020 17:42
December 16, 2020 17:31
December 16, 2020 17:31
December 16, 2020 21:54


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
4.x >= 14
3.x >= 13
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>
  `,
})
export class ErrorComponent {
  @Input() view: Content | undefined;
}


@NgModule({
  imports: [DynamicViewModule]
})
class ErrorModule {}

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

<h5>Component</h5>
<ng-container *dynamicView="component; injector: injector"></ng-container>

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

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

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

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"></ng-container>
    </div>
  `
})
export class FooComponent {
}

@NgModule({
  imports: [TeleportModule]
})
export class FooModule {}

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

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

@Component({ 
  template: `
    <section *teleportTo="someId">
      {{ value }}
    </section>
  `
})
export class BarComponent {
  value = '...'
}

@NgModule({
  imports: [TeleportModule]
})
export class BarModule {}

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 {
  componentRef: CompRef;

  constructor(private viewService: ViewService) {}

  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{

  constructor(private viewService: 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({
  component: Type<C>;
  injector: Injector;
  environmentInjector: EnvironmentInjector;
  context: Record<string, any>;
  vcr: ViewContainerRef | undefined;
  appRef: ApplicationRef | undefined;
})

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

createTemplate

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

createTemplate({
  tpl: TemplateRef<C>;
  context: C;
  vcr: ViewContainerRef | undefined;
  appRef: ApplicationRef | undefined;
  injector: Injector | undefined;
})

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 {
  constructor(private viewService: 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