GithubHelp home page GithubHelp logo

dynamic-comp-app's Introduction

DynamicCompApp

Hi everyone,

I would like to show you how to load a component dynamically in Angular project at runtime.

If you are working on Angular, you might know component templates are not always fixed. During the product development, you also have come across to load a component dynamically at runtime.

So let's begin to load component dynamically.

Entry

I will show you a web page and there will be 3 buttons. These buttons will load it's components dynamically. I have selected FrontEnd frameworks like, Angular, Vue, React.

Whichever framework button you press, that framework component will be loaded dynamically.

Define Directive

First of all, we need to define a directive like below. Because we need to tell to Angular where to put components in the UI.

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({ selector: '[framework-host]' })
export class FrameworkDirective {
    constructor(public viewContainerRef: ViewContainerRef) { }
}

This directive uses ViewContainerRef to access to view container element. We will use framework-host name that defined in @Directive clause.

Loading Component

I will show you my main app.component.ts and .html files part to load dynamically component.

html file;

  <div class="card-container">
    <button (click)="loadDynamicComponentsWithIndex(0);" class="btn btn-outline-danger m-2"> <img
      width="40"
      alt="Angular Logo"
      src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="
    />Angular</button>
    <button (click)="loadDynamicComponentsWithIndex(1);" class="btn btn-outline-success m-2"><img src="https://img.icons8.com/color/48/000000/vue-js.png"/>VueJS</button>
    <button (click)="loadDynamicComponentsWithIndex(2);" class="btn btn-outline-info m-2"><img src="https://img.icons8.com/color/48/000000/react-native.png"/>ReactJS</button>  
  </div>

  <!--Dynamic component area-->
  <div class="card-container">
    <ng-template framework-host></ng-template>
  </div>

We need to use <ng-template to use to load dynamically component. The framework-host defined before as directive. Our dynamic component will be there.

ts file;

Before show you app.component.ts, I would like to describe other things in project.

The first one is component interface that name is FrameworkComponent. This will use to pass a data to dynamic components. This interface like below.

export interface FrameworkComponent {
	data: any;
}

The another important thing is defining FrameworkItem class to create a FrameworkComponent list.

import { Type } from '@angular/core';

export class FrameworkItem {
  constructor(public component: Type<any>, public data: any) {}
}

Dynamic components;

We have 3 components, they are AngularComponent, VueComponent, ReactComponent.

export class AngularComponent implements OnInit, FrameworkComponent{

  @Input('data') data: any;

  constructor() { }

  ngOnInit(): void {
  }

}

html;

<h2>{{data.name}} component selected</h2>
<img src="https://upload.wikimedia.org/wikipedia/commons/c/cf/Angular_full_color_logo.svg">

After above methods, I could easily explain below code. We are loading dynamic components with getFrameworkList. This method includes FrameworkItem arrays. First of all we are loading a component that index is 0 (AngularComponent).

ComponentFactoryResolver is very important to load dynamic component. Firstly, we implement as a dependency componentFactoryResolver. After injected componentFactoryResolver, we will use it in loadDynamicComponentsWithIndex method to load dynamic component like below. We access to directive's viewContainerRef and create component ref with generated by resolveComponentFactory method.

After all, you will see the dynamic component changes in the UI.

  loadDynamicComponentsWithIndex(ind: any) {
    const frameworkItem = this.frameworks[ind];

    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(frameworkItem.component);

    const viewContainerRef = this.frameworkHost.viewContainerRef;
    viewContainerRef.clear();

    const componentRef = viewContainerRef.createComponent(componentFactory);
    (<FrameworkComponent>componentRef.instance).data = frameworkItem.data;
  }

Full code of app.component.ts.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  title = 'dynamic-comp-app';

  frameworks: FrameworkItem[];

  @ViewChild(FrameworkDirective, { static: true }) frameworkHost: FrameworkDirective;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

  ngOnInit(): void {
    this.frameworks = this.getFrameworkList();
    this.loadDynamicComponentsWithIndex(0);
  }

  loadDynamicComponentsWithIndex(ind: any) {
    const frameworkItem = this.frameworks[ind];

    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(frameworkItem.component);

    const viewContainerRef = this.frameworkHost.viewContainerRef;
    viewContainerRef.clear();

    const componentRef = viewContainerRef.createComponent(componentFactory);
    (<FrameworkComponent>componentRef.instance).data = frameworkItem.data;
  }

  getFrameworkList() {
    return [
      new FrameworkItem(AngularComponent, { name: 'Angular' }),
      new FrameworkItem(VueComponent, { name: 'VueJS' }),
      new FrameworkItem(ReactComponent, { name: 'ReactJS' })
    ];
  }

}

Demo show like below;

Dynamic Component Demo

I tried to show you about loading dynamic component to your Angular project.

I hope you enjoy when reading.

Have a nice coding...

References

  1. angular.io

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.