In the tutorial, grokonez.com shows how to dynamically load an Angular components by examples. What we introduce:
- Create Anchor Directive
- Dynamically Loading and Resolving Components
Related posts:
– Angular 6 Component – How to create & integrate New Angular 6 Component
– Angular 6 Routing/Navigation – with Angular Router Service
Overview
An Agnular application may need to load new components at runtime, so component’s templates are not always fixed.
The following examples shows how to build an dynamic news banner.
New news components are added frequently so it is impractical to use a template with a static component structure.
Angular Anchor Directive
We need define an anchor point to tell Angular where to insert components for adding a new components:
Now we build an NewsDirective
to mark valid insertion points in the template:
import { Directive, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[news-host]' }) export class NewsDirective { constructor(public viewContainerRef: ViewContainerRef) { } } |
– NewsDirective
injects ViewContainerRef
to access to the view container of the element that will host the dynamically added component.
news-host
is used to apply the directive to the element.
Angular Dynamic Loading Components
We implement an NewsBannerComponent
in news-banner.component.ts
file.
... @Component({ selector: 'app-news-banner', template: ` <div> <h2>Dynamic News Banner - Copyright by http://grokonez.com</h2> <ng-template news-host></ng-template> </div> ` }) export class NewsBannerComponent implements OnInit, OnDestroy { ... |
The
The
Angular Resolving Components
NewsBannerComponent
takes an array of NewsItem
objects as input that comes NewsService
.
NewsItem
object contains component object to load and any data to bind to the component.
import { Type } from '@angular/core'; export class NewsItem { constructor(public component: Type<any>, public data: any) { } } |
NewsService
returns the actual news content for banner:
import { Injectable } from '@angular/core'; import { SportNewsComponent } from './sport-news/sport-news.component'; import { NewsItem } from './news-item'; import { BusinessNewsComponent } from './business-news/business-news.component'; @Injectable({ providedIn: 'root' }) export class NewsService { getNews() { return [ new NewsItem(SportNewsComponent, { title: "2019 Women's World Cup: Spain's Women come back to beat South Africa", from: "euronews.com" }), new NewsItem(BusinessNewsComponent, { title: 'Walmart will save $30 million by putting new step stools in its warehouses', author: 'Lauren Thomas' }), new NewsItem(SportNewsComponent, { title: "Women's World Cup: Germany Women 1-0 China Women", from: 'bbc.com' }), new NewsItem(BusinessNewsComponent, { title: 'Elliott Management to acquire Barnes & Noble for $683 million', author: 'Lauren Hirsch' }) ]; } } |
NewsBannerComponent
loop through the array of NewsItems
and uses loadComponent()
to load a new component every 3 seconds.
export class NewsBannerComponent implements OnInit, OnDestroy { @Input() news: NewsItem[]; currentNewsIndex = -1; @ViewChild(NewsDirective, { static: true }) newsHost: NewsDirective; interval: any; constructor(private componentFactoryResolver: ComponentFactoryResolver) { } ngOnInit() { this.loadComponent(); this.getNews(); } ngOnDestroy(): void { clearInterval(this.interval); } loadComponent() { this.currentNewsIndex = (this.currentNewsIndex + 1) % this.news.length; let newsItem = this.news[this.currentNewsIndex]; let componentFactory = this.componentFactoryResolver.resolveComponentFactory(newsItem.component); let viewContainerRef = this.newsHost.viewContainerRef; viewContainerRef.clear(); let componentRef = viewContainerRef.createComponent(componentFactory); (<NewsComponent>componentRef.instance).data = newsItem.data; } getNews() { this.interval = setInterval(() => { this.loadComponent(); }, 3000); } } |
– NewsBannerComponent
uses ComponentFactoryResolver
to resolve a ComponentFactory
for each specific component.
– createComponent()
method returns a reference to the loaded component. Use that reference to interact with the component by assigning to its properties or calling its methods.
Note: to ensure that the compiler generates a ComponentFactory
for dynamically loaded components, we need add dynamically loaded components to the NgModule’s entryComponents array:
entryComponents: [SportNewsComponent, BusinessNewsComponent], |
NewsComponent Interface
To standardize the API for passing data to the components, we create an interface component: NewsComponent
.
export interface NewsComponent { data: any; } |
Then using it in all sub-news components:
– SportNewsComponent:
import { Component, OnInit, Input } from '@angular/core'; import { NewsComponent } from '../news.component'; @Component({ template: ` <div style="width:600px; padding:20px; background-color:powderblue;"> <h3>Sport News</h3> <h4>{{data.title}}</h4> <p>from: {{data.from}}</p> </div> ` }) export class SportNewsComponent implements NewsComponent { @Input() data: any; } |
– BusinessNewsComponent:
import { Component, OnInit, Input } from '@angular/core'; import { NewsComponent } from '../news.component'; @Component({ template: ` <div style="width:600px; background-color:green; padding:20px; color:red"> <h3>Business News</h3> <h4>{{data.title}}</h4> <p>Author: {{data.author}}</p> </div> ` }) export class BusinessNewsComponent implements NewsComponent { @Input() data: any; } |
Bootstrap App Component
We edit a bootstrap AppComponent
that shows app-news-banner
component. And it also injects NewsService
to provide NewsItem
data for NewsBannerComponent
:
import { Component } from '@angular/core'; import { NewsItem } from './news-item'; import { NewsService } from './news.service'; @Component({ selector: 'app-root', template: ` <div> <app-news-banner [news]="news"></app-news-banner> </div> ` }) export class AppComponent { news: NewsItem[]; constructor(private newsService: NewsService) { } ngOnInit() { this.news = this.newsService.getNews(); } } |
Sourcecode
– Project structure
– Source Code:
Angular-Dynamic-Loading-Components
Thank u for tutorial. please make another tutorial
Hi. Thank u for tutorial. Please make another tutorial.
Thanks! Easy to understand and apply to my source code.
Заказ
Awesome post! Keep up the great work! 🙂
Great content! Super high-quality! Keep it up! 🙂
Why no update from June 2019 onwards?????????????????
Wow, lovely portal. Thnx …
how can you add animation state to the component that is entering and the one that is leaving?
Narconon Rehab Drug Rehabilitation Clinics
I like checking your web site. Kudos!
Thanks a ton for sharing your excellent web site.
Ahaa, its nice dialogue regarding this post at this place at this weblog, I have read all that, so now me also commenting here. tastyandinteresting.be/beautiful-things/privatleasing-bil-bra-eller-dligt.php privatleasing bil bra eller dГҐligt
Белорусский трикотаж Свитмода|Молодежная женская одежда Свитмода|Одежда женская больших размеров Свитмода Бай|
Белорусский трикотаж Свитмода|Молодежная женская одежда Свитмода|Одежда женская больших размеров Свитмода Бай|
Hola y gracias por este blog es una verdadera inspiración ..
Nice artigo! Obrigado.. Perla Giusto Housen
Good luck to your blog as I continue to follow regularly. Carly Maxwell Straub
You do have a fabulous blog thanks. Ranice Wainwright Cahra
I like the valuable info you provide in your articles. I’ll bookmark your blog and check again here regularly. I am quite certain I’ll learn plenty of new stuff right here! Good luck for the next! Kissee Kalvin Marja
You have observed very interesting points! ps decent internet site. Lucina Nat Zalucki
Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. I have a dynamic component loader, and I need to pass in data through a service. I can get the data to display if I fire the function on
Your mode of telling everything in this article is truly pleasant, every one be able to simply understand it, Thanks a lot. Daniele Michal Gemina
Maja and Dima, I cannot wait to celebrate with you!! Soooo exciting, thank you for inviting me. Shannen Jecho Aurelius
uWrygICYOTHsXiw
You made some nice points there. I looked on the internet for the subject matter and found most individuals will agree with your site.
You made some nice points there. I looked on the internet for the subject matter and found most individuals will agree with your site.
You made some nice points there. I looked on the internet for the subject matter and found most individuals will agree with your site.
Hello! I could have sworn I’ve been to this blog before but after browsing through some of the post I realized it’s new to me. Anyways, I’m definitely happy I found it and I’ll be book-marking and checking back frequently!
There is a lot of misunderstanding about these issues today. Your material helps explain things. Chloris Germayne Ot
Simply wanna input that you have a very nice internet site , I love the design and style it actually stands out. Florencia Byrann Binni
Wonderful post! We will be linking to this particularly great post on our site. Keep up the good writing. Morna Kelley Kerby
You made some decent points there. I looked on the internet for the topic and found most individuals will consent with your blog. Loni Willem Saloma
Appreciate it for helping out, good information. Kenna Theo Rumery
Hello! I could have sworn I’ve been to this blog before but after browsing through some of the post I realized it’s new to me. Anyways, I’m definitely happy I found it and I’ll be book-marking and checking back frequently!
Hi there, constantly i used to check blog posts here early in the daylight, because i enjoy to learn more and more. Constantia Northrop Cristen
Appreciate it for helping out, wonderful information. Stefanie Tyson Houston
Hello! I could have sworn I’ve been to this blog before but after browsing through some of the post I realized it’s new to me. Anyways, I’m definitely happy I found it and I’ll be book-marking and checking back frequently!
Hello! I could have sworn I’ve been to this blog before but after browsing through some of the post I realized it’s new to me. Anyways, I’m definitely happy I found it and I’ll be book-marking and checking back frequently!
Hello! I could have sworn I’ve been to this blog before but after browsing through some of the post I realized it’s new to me. Anyways, I’m definitely happy I found it and I’ll be book-marking and checking back frequently!
You made some nice points there. I looked on the internet for the subject matter and found most individuals will agree with your site.
Hello! I could have sworn I’ve been to this blog before but after browsing through some of the post I realized it’s new to me. Anyways, I’m definitely happy I found it and I’ll be book-marking and checking back frequently!
Thanks for the post keep on sharing new things of you are looking for the twitter advertising agency then visit BrandBurp.