5.1 KiB
@title Dynamic Component Loader
@intro Load components dynamically.
@description Component templates are not always fixed. An application may need to load new components at runtime.
In this cookbook we show how to use ComponentFactoryResolver
to add components dynamically.
The following example shows how to build a dynamic ad banner.
The hero agency is planning an ad campaign with several different ads cycling through the banner.
New ad components are added frequently by several different teams. This makes it impractical to use a template with a static component structure.
Instead we need a way to load a new component without a fixed reference to the component in the ad banner's template.
Angular comes with its own API for loading components dynamically. In the following sections you will learn how to use it.
## Where to load the component
Before components can be added we have to define an anchor point to mark where components can be inserted dynamically.
The ad banner uses a helper directive called AdDirective
to mark valid insertion points in the template.
{@example 'cb-dynamic-component-loader/ts/src/app/ad.directive.ts'}
AdDirective
injects ViewContainerRef
to gain access to the view container of the element that will become the host of the dynamically added component.
The next step is to implement the ad banner. Most of the implementation is in AdBannerComponent
.
We start by adding a template
element with the AdDirective
directive applied.
The template
element decorated with the ad-host
directive marks where dynamically loaded components will be added.
Using a template
element is recommended since it doesn't render any additional output.
{@example 'cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts' region='ad-host'}
Resolving Components
AdBanner
takes an array of AdItem
objects as input. AdItem
objects specify the type of component to load and any data to bind to the component.
The ad components making up the ad campaign are returned from AdService
.
Passing an array of components to AdBannerComponent
allows for a dynamic list of ads without static elements in the template.
AdBannerComponent
cycles through the array of AdItems
and loads the corresponding components on an interval. Every 3 seconds a new component is loaded.
ComponentFactoryResolver
is used to resolve a ComponentFactory
for each specific component. The component factory is need to create an instance of the component.
ComponentFactories
are generated by the Angular compiler.
Generally the compiler will generate a component factory for any component referenced in a template.
With dynamically loaded components there are no selector references in the templates since components are loaded at runtime. In order to ensure that the compiler will still generate a factory, dynamically loaded components have to be added to their NgModule
's entryComponents
array.
{@example 'cb-dynamic-component-loader/ts/src/app/app.module.ts' region='entry-components'}
Components are added to the template by calling createComponent
on the ViewContainerRef
reference.
createComponent
returns a reference to the loaded component. The component reference can be used to pass input data or call methods to interact with the component.
In the Ad banner, all components implement a common AdComponent
interface to standardize the api for passing data to the components.
Two sample components and the AdComponent
interface are shown below:
The final ad banner looks like this: