Component templates are not always fixed. An application may need to load new components at runtime.
This cookbook shows you how to use
ComponentFactoryResolver to add components dynamically.
- Dynamic component loading
- The directive
- Final ad banner
Dynamic component loading
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, you 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.
Before you can add components you have to define an anchor point to tell Angular where to insert components.
The ad banner uses a helper directive called
mark valid insertion points in the template.
ViewContainerRef to gain access to the view
container of the element that will host the dynamically added component.
@Directive decorator, notice the selector name,
that's what you use to apply the directive to the element.
The next section shows you how.
Most of the ad banner implementation is in
To keep things simple in this example, the HTML is in the
template property as a template string.
<ng-template> element is where you apply the directive you just made.
To apply the
AdDirective, recall the selector from
ad-host. Apply that to
<ng-template> without the square brackets. Now Angular knows
where to dynamically load components.
<ng-template> element is a good choice for dynamic components
because it doesn't render any additional output.
Take a closer look at the methods in
AdBannerComponent takes an array of
AdItem objects as input,
which ultimately comes from
AdItem objects specify
the type of component to load and any data to bind to the
AdService returns the actual ads making up the ad campaign.
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
and loads a new component every 3 seconds by calling
loadComponent() method is doing a lot of the heavy lifting here.
Take it step by step. First, it picks an ad.
How loadComponent() chooses an ad
loadComponent() method chooses an ad using some math.
First, it sets the
currentAddIndex by taking whatever it
currently is plus one, dividing that by the length of the
AdItem array, and
using the remainder as the new
currentAddIndex value. Then, it uses that
value to select an
adItem from the array.
loadComponent() selects an ad, it uses
to resolve a
ComponentFactory for each specific component.
ComponentFactory then creates an instance of each component.
Next, you're targeting the
exists on this specific instance of the component. How do you know it's
this specific instance? Because it's referring to
adHost is the
directive you set up earlier to tell Angular where to insert dynamic components.
As you may recall,
ViewContainerRef into its constructor.
This is how the directive accesses the element that you want to use to host the dynamic component.
To add the component to the template, you call
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.
Generally, the Angular compiler generates a
for any component referenced in a template. However, there are
no selector references in the templates for
dynamically loaded components since they load at runtime.
To ensure that the compiler still generates a factory,
add dynamically loaded components to the
A common AdComponent interface
In the ad banner, all components implement a common
AdComponent interface to
standardize the API for passing data to the components.
Here are two sample components and the
AdComponent interface for reference:
Final ad banner
The final ad banner looks like this: