Video details

Structural Directives in Angular – How to Create Custom Directive (2022)


With this video tutorial, I would like to start a video series dedicated to structural directives in Angular. This kind of directive is a very powerful tool that allows you to manipulate with DOM elements and reshare that logic across your Angular application. From this video, you will learn how to create a custom structural directive and how to make your directive configurable by using a special micro syntax designed specifically for this kind of directive. I am quite sure that you will learn something cool today, so stay tuned, subscribe and enjoy the video!
-15% OFF For All My Courses 🔥 Use coupon: YOUTUBE_DISCOUNT during the purchase
Courses: ⭐ Angular Interview Hacking 🔗
⭐ Angular Material Theming Course (Advanced) 🔗
⭐ Performant Graphql Backend in 1 Day by Using Hasura Engine 🔗
🕒 Time Codes: 00:00:00 - Intro; 00:00:38 - Basic Structural Directive implementation; 00:15:51 - Outro;
#angular #webdevelopment


Hi everyone. Welcome. My name is Dmitro. I am an author of Decoded Frontend Channel. This is the channel about advanced NVR topics and web development. Today I would like to start a video series dedicated to structural directives in Angular and we will start to cover the very basic micro syntax which is being used for this kind of directives. And in the following videos we will dive deeper into more advanced things. So stay tuned and let's get into the details. So here you can see a brand new Angular application which I created specifically for this tutorial and it consists from only one Angular component and has very basic layout right here. And in this video I would like to implement the next functionality. So I would like to hide some part of my template as example this banner after some period of time, let's say after 5 seconds. So it's going to be something similar to NGF but with some delay. And in order to implement this functionality I decided to go with structural directive because it is exactly the kind of directives which allows you to manipulate with Dome so you can either reshape it or remove or add something plates and it's good to encapsulate this functionality in some directive which I could reuse within my application or even extract it to the library and shipped to other teams. So let's get started and implement our first structural directive. And in order to generate the directive I will be using the angular. Cli. So I will type ng generate directives just shortcuts GND. I will generate directive which called hide after I decided to call it like that. Once I press enter angular. Cli will generate the empty directive for me and it will add this to the declarations array inside the app model. Okay, let's jump to the directive and let's a little bit rename it. I just want to have hide after to not have this prefix but in real applications of course it's good to prefix your application directives components in order to avoid the collision with components and directives from third party libraries. And at this point as you can see there's no difference between structural and attribute directives at all. They look the same. The difference is obviously in the implementation and in the way how we attach this directive. If you remember attribute directive you attach like this, you just add it here and you are ready to go with structural directives. You have to add the asterisks in front of the directive name. So doing this you use this directive as a structural directive and you can see the first result. Our banner has disappeared and it might be quite strange behavior like why when we attach the empty structural directivity disappears. The thing is that this asterisks it is a Syntax's sugar which wraps under the hood our HTML where we attach this directive into ng template. So basically it looks like this. Here we go, move it inside here. And as you may know, Ng templates are lazy so we have to explicitly instruct Angular to render them. And that's why we see actually nothing on our screen. So let's revert it back and I will show you how to actually render this template in our view. In order to render it, we have to go to our directive and we have to inject two things. We have to inject reference to the container where we're going to render the template and we have to inject the reference to the template itself. This is how we can do it. Here I inject view container ref. This is where we're going to render it. And now I want to inject the template and template ref is a generic. So we have to define the type of the template to ref. But in this case it will be okay if we say that the type is any cool. So let's save it. And the second step is actually we have to instruct the angular to render our injected template in the injected view container and I will do it inside lifecycle hook. So let's implement this interface. And here below I'm going to create my NGO init method. And inside I say that view container. Ref should create embedded view. And as an argument for this method we have to provide our template. Cool. And now if I save it you can see that our banner got back. All right, the next thing we have to do is to provide somehow values right? So we have to configure the directive to hide the view after some period of time and we have to do it via inputs. Right. So let's implement our input. And I'm going to say that this is the input name delay which is zero by default and there inside and joining it. We would like to have something like this like set timeout and after some delay which we going to define via input, we have to remove this banner. And in order to clean up the view container ref we have to call the method clear. So clear will remove all rendered templates inside this view container. Ref. Now if we save it we will see that banner again disappeared because we have zero delay and it will be immediately disappeared. So that's fine. But let's try to provide some input to change the delay. And if you try to apply it like this you will get an error and it says that we cannot buy delay since it is not a known property of the section and this is only the first difference with the attribute directives. You cannot provide inputs like this and you know why? Try to guess it. This is because what I showed you before, that structural directives, they are wrapping it into template. So angular tries to resolve this input as a property of the section which doesn't obviously exist. And if you use the notation with ng template it would work. As you can see we have the banner and then after some time it disappeared after 5 seconds which I defined. And if you want to use inputs with this asterisks notation you have to use the special syntax for those directives. So let's revert it back and for input values we are not going to use this notation but input values for these kind of directives are provided inside these quotes. So I would like to have the next syntax I want to provide it just like that. So hide after 5000 milliseconds it is easy to read and yeah it's quite short notation so if I want to achieve it like this I have to name my input exactly the same way as the prefix of the directive. So I need to copy it and then I have to rename my input to this notation and then if I save it and of course I will update it here, it will be working fine because if you have input with the same name as a selector you can use this notation. Okay, I hope it is clear. Also Alternatively you can provide it here like hide after but then you could just rename it like this. So this is string inside the input. It describes your API. This is how the user of this directive interact with and this is just for internal implementation. So I will leave it as it is because in context of the class itself I think delay has better name rather than hide after so I will leave it as it is. All right cool. So our directive is working but check this out. After 5 seconds my banner disappeared and I see nothing. But what if I would like to render another template instead of it? Right, some placeholder like here was rendered banner or whatever and I want to have it somehow similar to NGF. If you know that we can do ng EV and then we can do something like else and render some placeholder in this case this else or in our case let's rename it to then and this then is just another input for the directive. And if we want to get this value for then input we have to obviously create a new one. And here very important you have to add the prefix of the directive. So hide after and then with the camel case you have to attach this then word like that. Of course if you want to have another keyword let's say later as example then you can name it like this but then you have to rename it like that. Okay, so I hope it is clear but for my case I think then sounds better. So I will rename it and then I say that it is a placeholder where the type either template ref of any or it could be null and by default it's going to be null. And now inside our set timeout once I clear my view, I have to check if we have placeholder. If it's not now, then we have to render it. And the way we render it we already know we just have to create embedded view and then we have to provide our placeholder as easy as that. And now if we save it we'll get an error. Of course because we don't provide a placeholder yet. This placeholder has no reference inside our template so we have to create one. I will say so this section will be rendered instead of our content and in order to assign this placeholder to them we have to create a template variable like that. So this template reference will be eventually the input for our then input. And now if I save it, nothing happened. Sorry. We have to provide the Ng template, not the HTML element and then create reference not to the HTML element but to the template. And then I can copy this template and paste it inside the Ng template. So here we go. And now once we save it you can see banner. 5 seconds passed and we have the placeholder instead of our first banner. And though I showed you very basic features of this microsyntex, for structural directive, check out how cool and clean way you can already implement some features like ours example. It is very easy to understand what's going on here like section hide after 5 seconds, then render placeholder and it is highly reusable because you can take this directive and apply to another HTML snippet and it will just work. Some of you who are more experienced with structural directives you may have seen like for NGF directive you can use as syntax and then assign this value to some another variable and then reuse this variable somewhere inside the template like that. In our case it will not work. It will require a bit more advanced things like context in structural directives which we will cover in the next video. All right guys, that was it. I hope everything was clear. I know that this topic might be not so easy to understand, especially for those who just started with Angular. However, I tried to do my best in order to make these things clear. Anyway, if you liked this video, please share this video with your colleagues and friends. Leave your thoughts in the comment section and don't forget that this is just the first part of the whole video series. In the next video we will dive into more advanced stuff. So if you like this video, if you are looking forward for the next one, you know what to do in order to not miss it. Additionally, don't forget that I have also video courses which might help you with your Angular carrier. Check them out, they're really cool. Links will be in the video description as well as coupon code and I wish you productive week ahead. Stay safe and see you in the next video.