The Power of Structural Directives in Angular

Netanel Basal
Netanel Basal
Published in
4 min readMar 22, 2017

--

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.
  • 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!

--

--

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.