Skip to content

Dynamic components with full life-cycle support for inputs and outputs for Angular

License

Notifications You must be signed in to change notification settings

hpawe01/ng-dynamic-component

 
 

Repository files navigation

ng-dynamic-component

Dynamic components with full life-cycle support for inputs and outputs

Travis CI Coverage Code Climate Npm Npm Downloads Licence semantic-release

Version 1+ supports Angular 4+ For Angular 2 please use ng-dynamic-component@^0.0.1

Installation

$ npm install ng-dynamic-component --save

Usage

Import DynamicModue with dynamic components you want to insert later:

import { DynamicModue } from 'ng-dynamic-component';
import { MyDynamicComponent1, MyDynamicComponent2 } from './my-components';

@NgModule({
  imports: [
    DynamicModule.withComponents([MyDynamicComponent1, MyDynamicComponent2])
  ]
})

Then in your component's template include <ndc-dynamic> where you want to render component and bind from your component class type of component to render:

@Component({
  selector: 'my-component',
  template: `<ndc-dynamic [ndcDynamicComponent]="component"></ndc-dynamic>`
})
class MyComponent {
  component = Math.random() > 0.5 ? MyDynamicComponent1 : MyDynamicComponent2;
}

You can also pass inputs and outputs to your dynamic components:

@Component({
  selector: 'my-component',
  template: `<ndc-dynamic [ndcDynamicComponent]="component"
                          [ndcDynamicInputs]="inputs"
                          [ndcDynamicOutputs]="outputs"
                          ></ndc-dynamic>`
})
class MyComponent {
  component = MyDynamicComponent1;
  inputs = {
    hello: 'world',
    something: () => 'can be really complex'
  };
  outputs = {
    onSomething: (type) => alert(type)
  }
}

Here you can update your inputs (ex. inputs.hello = 'WORLD') and they will trigger standard Angular's life-cycle hooks (of course you should consider which change detection strategy you are using).

You can also use NgComponentOutlet directive from @angular/common instead of <ndc-dynamic> and apply inputs and outputs to your dynamic components:

@Component({
  selector: 'my-component',
  template: `<div *ngComponentOutlet="component"
                   [ndcDynamicInputs]="inputs"
                   [ndcDynamicOutputs]="outputs"
                   ></div>`
})
class MyComponent {
  component = MyDynamicComponent1;
  inputs = {...};
  outputs = {...}
}

You can have more advanced stuff over your dynamically rendered components like setting custom injector ([ndcDynamicInjector]) or providing additional/overriding providers ([ndcDynamicProviders]) or both simultaneously or projecting nodes ([ndcDynamicContent]).

NOTE: In practice funtionality of this library is splitted in two pieces:

  • one - component (ndc-dynamic) that is responsible for instantianting and rendering of dynamic components;
  • two - directive (ndcDynamic also bound to ndc-dynamic) that is responsible for carrying inputs/outputs to/from dynamic component by the help of so called ComponentInjector (it is ndc-dynamic by default).

Thanks to this separation you are able to connect inputs/outputs and life-cycle hooks to different mechanisms of injecting dynamic components by implementing ComponentInjector and providing it via DynamicModule.withComponents(null, [here]) in second argument.

It was done to be able to reuse NgComponentOutlet added in Angular 4-beta.3.

License

MIT © Alex Malkevich

About

Dynamic components with full life-cycle support for inputs and outputs for Angular

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 84.0%
  • JavaScript 16.0%