dynamic-loader-app

Background

Components are the building blocks of any Angular 2 application. We usually create our components and then define where and how they are included. A component is loaded using either an HTML tag (following the component’s selector) or by using a router outlet if we have routing in place (You can read more about Routing in a previous post). In many cases, we find ourselves needing to load components dynamically (on demand) by following a certain criteria or state that is not represented by route. Cases when we don’t know how the DOM structure is going to be like (Think about composing components on your page based on a JSON feed). In this final post of the Introduction to Angular 2 series, we are going to look at how we can load components dynamically. Keep in mind that by the time Angular 2 is released, the syntax might slightly alter (It did for DynamicComponentLoader a few times).

The Application

In this column, I am going to demonstrate how to build a simple application which contains two components loaded on Demand. The green element is a header component which is loaded as a root (first in the series) component. The red element is a news list component loaded in place using a special selector. I am going to use the Angular CLI for that purpose.

dynamic-loader-app

Our app.component.html is pretty simple:

Basics

Angular 2 has a DynamicComponentLoader service that allows us to dynamically load a component in a certain position on the page. Just like any other service, we will need to inject it to be able to reference it.

The service as in (RC 2), has two functions that we can use:

LoadAsRoot

The loadAsRoot function creates an instance of a root component and places it at the first element that matches the component’s selector. The function takes three parameters. The first one being a Type or Binding. it’s basically the type of component that we are trying to load. The second one is an override of the selector which determines which element in the DOM is going to host our dynamically generated component. The third one is an injector that is used to instantiate the component.

We are using the ngAfterViewInit lifecycle hook to create the instance of our component. At the time of writing, the DynamicComponentLoader service still has issues with databinding when loading a root component (see here). I am confident it will be resolved soon and we won’t need the workaround introduced in this example.

The loadAsRoot function returns a promise (One of the few areas in Angular 2 where promises are used). That is why the promise needs to hold a reference to the future component (hence the returned compRef). Ideally we should manually destroy the component when it’s no longer needed.

LoadNextToLocation

The loadNextToLocation function creates an instance of the component and loads it into the component view of the provided ElementRef immediately after the element with the given name.

In this example we are using the #newsList selector to determine our ViewChild. The function requires a minimum of two parameters. The first parameter, just like loadAsRoot, is a Binding or Type (type of component). The second one is the component instance that we are targeting. In our case, we are using the @ViewChild annotation to get access to the component. You can optionally provide an array of providers to configure the injector provisioned for this component instance.

Our complete app.component.ts looks like the following:

Conclusion

In this post we’ve looked at the DynamicComponentLoader service which dynamically loads components into an Angular 2 application. It is the service that the router outlet component is using under the hood to dynamically load components based on the activated route.

The following two tabs change content below.
George has been working with leading-edge programming tools since 2002. Driven by his belief in the modern web and his ability to assimilate and utilize emerging technologies, he has been working with customers from all over the world in a wide range of industries including banking, insurance, retail, design, advertising, ecommerce, education, tourism and real estate. He has in depth knowledge of the .NET platform and specializes in ASP.NET Webforms, MVC, HTML5 and JavaScript, Restful Services and SQL Server to deliver web enterprise solutions. When he is not coding or learning something new, George is either working out, road tripping, playing basketball or spinning the latest tracks with his DJ friends.