Slide 1

Slide 1 text

IT’S ALIVE! DYNAMIC COMPONENTS IN ANGULAR Shmuela Jacobs

Slide 2

Slide 2 text

Shmuela Jacobs Front-end Consultant & Trainer, GDE shmool @ShmuelaJ

Slide 3

Slide 3 text

DEMO

Slide 4

Slide 4 text

STATIC COMPONENTS

Slide 5

Slide 5 text

STATIC COMPONENTS ➤ Used in template ➤ Known in development time ➤ Fixed location ➤ Hard-coded

Slide 6

Slide 6 text

STATIC COMPONENTS?

Slide 7

Slide 7 text

STATIC COMPONENTS

Slide 8

Slide 8 text

IMAGINE...

Slide 9

Slide 9 text

DYNAMIC COMPONENTS

Slide 10

Slide 10 text

DYNAMIC COMPONENTS ➤ Added in run time ➤ Load the configuration from the server ➤ Lazy loaded
@ViewChild('vc', { read: ViewContainerRef }) vc; constructor(private cfr: ComponentFactoryResolver){} this.components.forEach(component => { this.vc.create(this.cfr.resolveComponentFactory(component)) });

Slide 11

Slide 11 text

DYNAMIC COMPONENTS ➤ Dashboards

Slide 12

Slide 12 text

DYNAMIC COMPONENTS ➤ Dashboards ➤ Data-driven forms

Slide 13

Slide 13 text

DYNAMIC COMPONENTS ➤ Dashboards ➤ Data-driven forms ➤ Popups & Modals

Slide 14

Slide 14 text

DYNAMIC COMPONENTS ➤ Dashboards ➤ Data-driven forms ➤ Popups & Modals ➤ Content Management Systems ➤ Example: Angular.io

Slide 15

Slide 15 text

DYNAMIC COMPONENTS ➤ Dashboards ➤ Data-driven forms ➤ Popups & Modals ➤ Content Management Systems ➤ Example: Angular.io ➤ Embedded into foreign components ➤ Example: JointJS (Backbone) Juri Strumpflohner
 Use Dynamic Components to render HTML for 3rd party libraries
 https://juristr.com/blog/2017/11/dynamic-angular-components-for-rendering-html

Slide 16

Slide 16 text

DYNAMIC COMPONENTS ➤ Dashboards ➤ Data-driven forms ➤ Popups & Modals ➤ Content Management Systems ➤ Example: Angular.io ➤ Embedded into foreign components ➤ Example: JointJS (Backbone) ➤ Plugins ➤ Example: Wizer.Me Maxim NgWizard Koretskyi Modules are not what you think they are

Slide 17

Slide 17 text

COMPONENT INSTANTIATION NgModule Declarations compile SomeComponent SomeComponent Factory create SomeComponent View DOM Node Component Instance render

Slide 18

Slide 18 text

COMPONENT INSTANTIATION NgModule Declarations Entry Components compile SomeComponent SomeComponent Factory create SomeComponent View DOM Node Component Instance render this.vc.create( this.cfr.resolveComponentFactory(component)) }); SomeComponent Host Factory

Slide 19

Slide 19 text

DYNAMIC COMPONENTS ➤ Where is the component inserted? ➤ How is it instantiated? @Component({ template: `
` }) export class HomeComponent { @ViewChild('vc', { read: ViewContainerRef }) vc; constructor( private injector: Injector, private cfr: ComponentFactoryResolver) {} addDynamicComponent() { const cmpFactory = this.cfr.resolveComponentFactory(NoteComponent); const componentRef = cmpFactory.create(this.injector); this.vc.insert(componentRef.hostView); }

Slide 20

Slide 20 text

DYNAMIC COMPONENTS ➤ Where is the component inserted? ➤ How is it instantiated? constructor( private cfr: ComponentFactoryResolver) {} addDynamicComponent() { const cmpFactory = this.cfr.resolveComponentFactory(NoteComponent); // const componentRef = cmpFactory.create(this.injector); // this.vc.insert(componentRef.hostView); this.vc.createComponent(cmpFactory); } @Component({ template: `
` }) export class HomeComponent { @ViewChild('vc', { read: ViewContainerRef }) vc;

Slide 21

Slide 21 text

DYNAMIC COMPONENTS ➤ How to pass inputs? ➤ How to bind to outputs? ➤ Notice: Change detection works, 
 but ngOnChanges will not be called (ngDoCheck will) componentRef.instance.data = this.getData(); componentRef.instance.event.subscribe(console.log)

Slide 22

Slide 22 text

DYNAMIC COMPONENTS ➤ It's still not 100% dynamic... const cmpFactory = this.cfr.resolveComponentFactory(NoteComponent);

Slide 23

Slide 23 text

DYNAMIC DYNAMIC COMPONENTS

Slide 24

Slide 24 text

PLUGIN COMPONENTS

Slide 25

Slide 25 text

PLUGIN COMPONENTS ➤ Unknown in compile time ➤ Lazy loaded modules constructor( private injector: Injector, private loader: NgModuleFactoryLoader) {} addPlugin() { this.loader.load('path/to/plugin/plugin.module#PluginModule') .then((factory) => { const module = factory.create(this.injector); const cfr = module.componentFactoryResolver; const cmpFactory = cfr.resolveComponentFactory(PluginComponent); this.vc.createComponent(cmpFactory); }); }

Slide 26

Slide 26 text

PLUGIN COMPONENTS ➤ Build a module separately with Angular CLI - angular.json "projects": { "ng-talks-demo": { ... "architect": { "build": { ... "options": { "lazyModules": [ "path/to/plugin/plugin.module" ], ...

Slide 27

Slide 27 text

PLUGIN COMPONENTS ➤ Unknown in compile time ➤ Lazy loaded modules constructor( private injector: Injector, private loader: NgModuleFactoryLoader) {} addPlugin() { this.loader.load('path/to/plugin/plugin.module#PluginModule') .then((factory) => { const module = factory.create(this.injector); const cfr = module.componentFactoryResolver; const cmpFactory = cfr.resolveComponentFactory(PluginComponent); this.vc.createComponent(cmpFactory); }); }

Slide 28

Slide 28 text

PLUGIN COMPONENTS ➤ Use providers! @NgModule({ declarations: [PluginComponent], entryComponents: [PluginComponent], providers: [ { provide: 'widgets', useValue: [ { name: 'plugin-cmp', component: PluginComponent } ], multi: true } ] }) export class PluginModule {}

Slide 29

Slide 29 text

PLUGIN COMPONENTS ➤ Unknown in compile time ➤ Lazy loaded modules constructor( private injector: Injector, private loader: NgModuleFactoryLoader) {} addPlugin() { this.loader.load('path/to/plugin/plugin.module#PluginModule') .then((factory) => { const module = factory.create(this.injector); const cfr = module.componentFactoryResolver; const widgets = module.injector.get('widgets'); const cmpFactory = cfr.resolveComponentFactory(widgets[0][0].component); this.vc.createComponent(cmpFactory); }); }

Slide 30

Slide 30 text

DYNAMIC PLUGIN COMPONENTS!

Slide 31

Slide 31 text

DYNAMIC COMPONENTS - MY RESOURCES ➤ Juri Strumpflohner
 Use Dynamic Components to render HTML for 3rd party libraries
 https://juristr.com/blog/2017/11/dynamic-angular-components-for-rendering-html ➤ Maxim NgWizard Koretskyi ➤ Modules are not what you think they are - UP NEXT! ➤ Here is what you need to know about dynamic components in Angular
 https://blog.angularindepth.com
 ➤ Manfred Steyer 
 Angular Elements Dashboard
 https://github.com/manfredsteyer/angular-elements-dashboard

Slide 32

Slide 32 text

Thank You! Shmuela Jacobs shmuela@ng-girls.org shmool @ShmuelaJ ng-girls.org