7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
FREELessons: 22Length: 2 hours

Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

7.2 Creating A Directive

This video covers recreating the ng-click directive and a “clickable” element with the link phase of directive compilation, via scope evaluation and a brief look at transclusion.

7.2 Creating A Directive

In this video we're going to create ourselves a directive. I'm going to be building a version of the ng-click directive. But if you need to look up the directive documentation then head to this URL on the Angular website, and it'll give you a really good in depth guide to creating directives and also have the search run. So here I have the beginnings of our directive app. I've got a controller code example, and I have a button here, with a message in it, that's defined in our controller down here. Then a function called click, and I've used the ng-click directive to say that when this button is clicked, we are going show an alert box with the scope message. So, now click that button, and we get a little message. What we're gonna do is reimplement the ng-click directive to just be called click. You can see this, I changed this. I clicked the button, and now nothing is happening. So we need to create our own directive. To do so, we use the same dot syntax we've learned from filters and controllers. So I'll say dot directive, and I'll give it a name. The name's quite important. In this case, it's just gonna be called click, but I'll go into some other examples later. And you can watch the previous video for a recap of all the different possible names of directives. Then again, we pass it a function. And from the function, instead of returning another function, we can return an object. The object we return contains the properties of the directive that we're creating. An Angular has a set of properties that we can define that you can find on the website. Right about here that shows all the different things that we can set in this object in order to set up our directive. To start with, we're only going to use two of them, restrict and link. Restrict is what tells Angular how we can use the directive. There's a whole range of different options, and I'll show you them down on this page. You can see we can restrict our directive to the element name, an attribute, or inside a comment. In this case, I'm going to restrict us to the attribute cuz you can see here I've used click as an attribute of a button. The next things we're gonna do is pass a link function. The link function gets past each element instance, on which Angular finds our directive. It's given the scope, the element lived in. The element itself wrapped in a sort of light version of jQuery, and the attributes of the object. So, you can see we've got three parameters scope, element, and attributes or atters. Inside here we carry out all the behavior of our directive. In this case we're just building quite a simple one, and all we need to really do is attach a click handler to the element. And then use either scope or attributes to run the JavaScript contained in the click directive. Angular provide AJ crew like syntax for doing so. So I'm going to say element.bind, and I'm gonna bind to a click event and then call a function. When that element's clicked and the function runs, what we want to do is run the JavaScript contained in this click directive. We're going to use scope eval to evaluate the contents of the click attribute against the scope of the controller. In this case, the example controller. Then, we're going to grab the attribute out of the utters object. So I would say utters.click, I know it's .click because it's the name of our directive. Because in order to use this directive, we need to add the click attribute. Just to show you what I mean, I'm gonna cancel log the attribute object. If I open up my developer tools, and clear the console, and then refresh the page, you can see we get this EA object. This is a list of attributes. And you can see we have the click attribute with the string that we got from the attribute here. We can evaluate this, using Angular special eval method. So now, hopefully, when I click the button, we will get the scope message alerted out to us. And you can see we do. So there we've created our own version of the ng-click directive. Next let's take it a bit further and make our own element. I just closed the dev tools. So the first thing you need to do is change the restrict. I'm gonna make this e so we can create an element. And our element is going to be called a clicker. So I'm gonna change the name of the directive. Now instead of using a button, I'll make it a clicker. Then I believe the click attribute on that, because we still want to be able to define what it is that we want to happen when the button is clicked. Notice we no longer have a button, but we're going to use the directive template to turn this clicker into a button. Next I'm gonna define our template. So, it's gonna be a button. And I'll close off that button, and then fix my JavaScript. And you see now we have a button on our message and click element have completely disappeared. But this isn't ideal because if you're creating a reusable component like this clicker, you want to be able to pass templating data into it to have that exist inside the element you're creating. So in this case, we want the message to appear inside the button. In Angular, this is called transclusion. The first thing we have to do is include the ng transclude directive on the button. And then tell Angular that we want to allow transclusion and also that we want to replace this element. So I'm gonna say replace, as true. And transclude is true. And now you can see that the message that's set in our example controller appears inside a button. But we've never set up a button here. It's being transformed by the add directive, by our clicker directive. And it's being transcluded in, which means that the contents of our original clicker element is being copied inside the directive that we set up a template on. If I remove ng transclude from here you can see that the content is not copied in because we haven't told Angular that we want to be able to transclude data in. Transclusion is a complicated topic, and I'd recommend reading the Angular directive guide on it. And now when I click the button, you can see we are getting our hello message again because I've still got the same event handler going on, and it's still evaluating these same attributes. I can update this attribute and call it on click, and Angular will, again, normalize this. So I'm still logging the attributes if we look at the most recent, the EA object, you can see that it's normalized the on click attribute to be camel cased. So, I can update this to be on click. Click the button. And we get a hello message. To show you the same is true of the transformation of directive names, I'm going to rename my directive to my clicker. You can see I've use the camel case example here. But I'm going to use a dash example in the element here. So my dash clicker. And I'll copy that over to the end of the element too. But you can see when I click it, it still works. Angular is transforming the my-clicker name, and this could also be my:clicker, and it would still work. Angular is transforming these to match them up against my-clicker. So it's possible to build elements that might validate if you wanted to put it in a validator. In this case, this wouldn't validate, but there's other example of combinations of values that are transformed to the camel case version that would validate. So now we've created our own directive. There's a whole lot more you can do with directives. I haven't covered the compile step, but definitely do read the guide on AngularJS.org for more.

Back to the top