What’s a Structural Directive?

A Structural directive changes the DOM layout by adding and removing DOM elements.

The two most common structural directives you’ll come across are ngIf and ngFor .

Understanding the asterisk

The asterisk is syntactic sugar for something a bit more complicated

Let’s take for example the ngIf directive:

Angular will wrap the host element with a template tag.

element with a tag. Angular will transform the ngIf to be a property binding.

Create a Structural Directive

First, let’s understand how to create a structural directive. We are going to implement our simple copy of the ngIf directive.

We can use our directive like this:

<div *myNgIf=”condition”></div>

Let’s explain what is happening piece by piece.

TemplateRef — As the name suggest the TemplateRef is just a reference to the template .

ViewContainerRef —

If you think about it, eventually templates contain DOM elements, so if you need to insert an element, you need a place to “put” it. In Angular, this place is called a container. ViewContainerRef is a reference to the container.

Which element is the container in this case?

Angular will replace the template with a diagnostic comment that will represent the container.

Let’s see this in action.

The code above will generate this output —

The ViewContainerRef also exposes the createEmbeddedView() method that takes a template and renders its content as a sibling to the container. ( in our case the comment )

The final step is to create a setter as Input and based on the condition to create/clear the template.

Now that you understand how to create a structural directive let’s see two real life examples.

Show Content Based on the User Role —

Imagine that you need to show/hide content based on the user role. Let’s say you have a user stream that will give you the current user and you want to determine if he has permission to see the content based on his role.

Note: authService.user returns an observable.

The usage —

Very cool 😎 !

Create Range Directive —

You can see that in this case, we are passing the second parameter to the createEmbeddedView() method. Angular 2 templates have a special let syntax that allows you to define and pass a context when they’re being generated.

This will allow us to reference the variable we declared back on the *range=”[20,30]; let num” as local variable on that view. We use $implicit because we don’t know what name the consumer will assign to it when he uses the directive. ( it’s like we use ngFor=”let todo of todos” )

The second approach is to expose your context as keys that you defined, for example:

Now we can use our directive:

You can create more advanced directives like ngFor but this is for another post.

Things to not miss:

Follow me on Medium or Twitter to read more about Angular, Vue and JS!