ag-Grid is an enterprise datagrid that works with Angular 2. As ag-Grid works with many frameworks, the internals of the grid had to allow for Angular 2 rendering inside the grid despite ag-Grid not being written in Angular itself. This was done using Angular 2 Dynamic Components and we managed to do it while still supporting AOT. This blog details what we learnt along the way.

The Setup

To explain we present a simple sample application that isolates what we are trying to do. In our example below we are going to develop two main Modules — one will be a Library (in our case this was ag-Grid) that will display an array of dynamically created Components (similar to how ag-Grid displays Angular components inside the grid’s cells), and the other will be our actual Application.

The end result will be look like this:

You can find all the code for this example over at GitHub, and the live example over at GitHub.io

One further note — when we return to “user” below, we are referring to a user (or client) of the Library we’re writing.

The Library

Our Library is going to be a simple one — all it does is display an array of dynamically created Angular 2 Components. The main component looks like this:

As you can see it’s a pretty simple component — all it does is display the current cellComponentTypes . These are the user supplied components, and they can be any Angular 2 Component.

The interesting part of the Library is in the Cell Component:

You’ll notice that we don’t have a template here — that’s deliberate as the Cell doesn't have any content of its own - all it does is serve up the user supplied Component. The important part of this Component are these two lines:

let compFactory = this.cfr.resolveComponentFactory(this.componentType);

This line asks the ComponentFactoryResolver to find the ComponentFactory for the provided Component. We'll use this factory next to create the actual component:

this.viewContainerRef.createComponent(compFactory);

And that’s all there is to it from the Library Component side of things — we find the factory for the Component, and then create a new instance of the Component. Easy!

For this to work we need to tell Angular’s AOT Compiler to create factories for the user provided Components, or ComponentFactoryResolver won't find them. We can make use of NgModule.entryComponents for this - this will ensure that the AOT compiler creates the necessary factories, but for you purposes there is an easier way, especially from a users perspective:

By making use of ANALYZE_FOR_ENTRY_COMPONENTS here, we are able to add multiple components to the NgModule.entryComponents entry dynamically, in a user friendly way.

The Application

From the application side of things, the first thing we need to do is create the components we want to use in the Library — these can be any valid Angular 2 Component. In our case we have three similar Components:

@Component({

selector: 'dynamic-component',

template: '<div class="img-rounded" style="background-color: lightskyblue;margin: 5px"> Blue Dynamic Component! </div>',

})

export class BlueDynamicComponent {

}

All these components do is display a little styled text.

To register these in both our Application, and in the Library, we need to switch to the Application Module:

We declare our Components in the usual way, but we additionally need to register them with the Library (remember, this is the part where they’ll be added to the Library’s NgModule.entryComponent entry). We do this in this part of the module:

GridModule.withComponents([

BlueDynamicComponent,

GreenDynamicComponent,

RedDynamicComponent

])

Finally, we can take a look at the main Application Component:

It may look like theres a lot going on here, but the bulk of the template is to make it look pretty. The key parts of this Component are:

<button

type="button"

class="btn btn-primary" (click)="grid.addDynamicCellComponent(selectedComponentType)"

>

Add Dynamic Grid component

</button>

This will ask the Library to add a create a new instance of the supplied Component, and in turn render it.

<grid-component #grid></grid-component>

And this line is our Library Component.

That’s it — easy to write and use (from both an Application and Library perspective), and AOT (and JIT!) friendly.

Benefits of using AOT

The speed and size of the resulting application when using AOT can be significant. In our ag-grid-angular-exampleproject, we estimate the size of the resulting application went from 3.9Mb down to 2.4Mb — a reduction of just under 40%, without optimising for size or being particularly aggressive with rollup.

Speed-wise, the loading time when using AOT is significantly more responsive on startup — this makes sense given that Angular doesn’t have to compile all the code once again. Take a look at the examples project and try both the JIT and AOT versions out for yourself!

There’s so much more you can do if you decide to combine Angular 2 Components with ag-Grid — powerful functionality, fast grid and easy configuration. What are you waiting for?!