angular.element

John Lindquist
InstructorJohn Lindquist
Share this video with your friends

Social Share Links

Send Tweet
Published 11 years ago
Updated 5 years ago

A brief overview of using element in an AngularJS directive, and how to target one without jquery, and also how to use replace and compile function

John Lindquist: I want to talk briefly about angular elements and how they are a bit different from J-Query elements. Also, a little bit about the compile function, but not too much technical detail, just enough to get your brain going.

Here, I have a dumb-password element with a template of, "Hello, world." Basically, this is just to check that it's working. What I want to do is make this a template that has two things listed inside of it, so the first thing we'll be an input with a type of text, ng-model of say, "Model input." Then, the next one can be a div that just has the model input showing.

If I refresh here, let's just type something. We're good to go. You can see that we have dumb-password, wrapping our div, and then, inputting div inside of that div. One thing I'm going to do here. I've talked about this before, but I want to say, "Replace," and just say, "True," here. Because what that's going to do is -- watch when I refresh. You'll see that the dumb-password is gone away, and now, it's simply replacing dumb-password with that div.

Whereas before, this was wrapped with dumb-password, now it's just the div. This is going to make it a little bit easier to go under the children of the div, in just a second here. Because what I want to do is when the password equals the word "password," we'll do a little alert thing there. Say our linking function, we're going to say, "Scope watch."

There's another thing I haven't talked about, but it's pretty easy to set up. This just means we're going to watch our model input. We want to change as we can check the value for whatever we want. So, we'll say, "If value equals the word 'password', then console log change it," or something. We'll type in here say, "Password and our console say, 'change it'." I'll do it again. That's working.

What we want to do is dive into our element and change a class on an element inside of our template. What we could do right now is say, "Element, and get," put, "children." Then, "Get the children," and that will be the first one, because we want to grab this guy. Then, say, "Toggle class and alert box and alert."

Now, this, I think, is a terrible way of doing this, actually. I believe I did that wrong. Where's password? There we go. I didn't have to dive into that first level. Sorry, I got confused with "replace" for just a second there.

We dove into it and grabbed the second element, so this was the first one and this one is the second one, then toggled the class of an alert box. We just added the class on to it.

Now, this is a nasty way of looking this element up, because typically like in J-Query you will use something like, "find." You will use a selector to find it, or find by ID and things like that. That's actually not supported in Angular-JS. That's more for reasons of testing and things like that.

What we can do is get a reference to the element before we even put it on the doms. What I'm going to do is create an element in here, so let's look into our template. I'm going to grab this guy, delete him, and then, I'm going to create an angular element from him. Let's call it, "valid hold enter," or something like that.

Use angular element to create an element from this string. Then, we're going to talk about -- I mentioned, I'm going to talk about the compile function and this is where I'm going to do it. The compile function takes your template stuff, so this will be our template element, say, "TL, LM," or whatever. From here, we can just append our -- what do we call it -- valid element on to it.

I'm going to delete our linking function, real quick. You'll say it make a come-back really soon, but for right you can see that this is still working. It's still bound. We have a reference to the valid element. We append it to our template, but we lost all the scope stuff. So we need to rewire up the scope stuff.

What I'm going to do here is return. You return a linking function from the compile function. We can't reference a linking function inside of our object here anymore. We have to actually return it from here. We can just do this, "return," and then, everything should be wired up. "Wired," or I guess, "Password," is what I want to type.

You can see that it's still looking up the element by element "children-1." Instead, what we can do now, instead of saying, "Element children-1," I can just say, "Valid element." Now, I can say, "Password." You can see that "valid element" is a reference to that actual element. We're not searching for it. We're not finding it. We're not using the select or anything.

We have an actual reference to the element itself. We can apply any sort of -- adding classes or manipulate it however we want to. We, actually, don't even need this reference to the element to do that sort of stuff, because we have a full reference to the element there.

Just one note here before I finish. Just to keep this a bit cleaner. I'd like to create here something like this, or I just say, "This link," is that. It is that? I guess I copied and let's paste from the history. It's this one.

Then, from there, I can just say, "Return link," instead of returning the functions out of there. This will still work. Now, we have, just to quickly review, there's nothing to show in here. It's just the component itself. We had a "restrict" which is the element. It's going to replace the entire thing.

That's not wrapped in, if we look at the elements. This isn't wrapped in the dummy, or the dumb-password, it's just the div with the two elements inside of it. During the compile phase, we are appending him onto our template. That's right here. This is our template and this is -- we're just appending the valid element in there. Then, from there on out, all we're doing is watching for the input to change.

When it does change, we have our reference to that element and we can talk with the class or whatever we want to on that element itself. Hopefully, that makes sense. I'll go into more detail on things like "scope watch" and angular element and the compile phase in future videos. But for right now, hopefully, that clears might clear some things up for you.

Nicholas Westby
Nicholas Westby
~ 10 years ago

How are you typing into a second window and having that markup be injected into a string into your first window in WebStorm? Looks really nifty.

Roman Ganchenko
Roman Ganchenko
~ 10 years ago

Alt-tab > Edit HTML fragment

Karen
Karen
~ 10 years ago

I don't get the 'this.link' 'return link' logic. Why do we assign link like this.link but then refer to it in compile section like just 'link'?

John Lindquist
John Lindquistinstructor
~ 10 years ago

I updated the code to show the proper "var link" approach (I had this corrected with an overlay on YouTube, but missed it in migrating the videos).

This approach is simply a convenience, nothing more. You can leave the link function as an anonymous function "link: function(){...}" if you'd like. The only tricky part is that a compile function returns a link function, so using compile (which is an edge case) will look much different than the standard way of just using "link: function()" on a directive definition object".

Amit
Amit
~ 9 years ago

You were probably just demoing features but this approach should not be used in actual app as directive function is not executed repeatedly. And having multiple instances of directive breaks this example. Am I correct?

Markdown supported.
Become a member to join the discussionEnroll Today