Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 832 of the free egghead.io lessons, plus get Angular 1.x content delivered directly to your inbox!

Existing egghead members will not see this. Sign in.

Just one more step!

Check your inbox for an email from us and click link to unlock your lesson.

Building Zippy

7:55 Angular 1.x lesson by

Building a demo AngularJS directive named Zippy using ng-model, ng-click and transclusion (no controller)

Get the Code Now
click to level up

egghead.io comment guidelines


Building a demo AngularJS directive named Zippy using ng-model, ng-click and transclusion (no controller)


Are following scopes the same?
- the scope defined in the object returned by the directive definition,
- and the scope used in the link function???
If yes, would it mean that I could move the field isContentVisible and the function toggleContent into the upper scope definition??
Thank you in advance!

In reply to egghead.io
Roman Ganchenko

what do you mean in upper scope definition?
Do you mean in controller scope? If yes, the answer is Yes, you might do so, but then you will have to wrap your html into ng-controller, so it will have the same scope

In reply to glasson

Could you please update the source for angular 1.2? I can't seem to get this to work :(.

In reply to egghead.io

Could you please update the source for angular 1.2? I can't seem to get this to work :(.


It works as expected with 1.2.14. What issues are you having?

In reply to Rai

well... this is embarassing.

just tried again and it works.

not sure why I was having so many issues before!!


In reply to Joel

John Lindquist: Let's create a zippy directive which will combine some of the concepts we've learned so far, and also, maybe stretch ourselves are little by throwing in some new stuff. We'll just create an app here with zippy in it.

We'll start with our app. Say, "App directive zippy," return. "Restrict E," for element and then, with a template of -- we'll just say for now -- "div and Hello, world"

Just to make sure this is working. We'll keep our console open in case I make any mistakes.

We have "Hello, world" working. Basically, what we're going to do here is build a component that, when you click on the title, it'll expand and show you the content. When you click on the title again, it will collapse and hide the content.

Inside of our zippy component, we're also going to have some content. We'll say, "This is the content," because that's a great content.

We'll have a title that we pass in from an input, I guess. This is kind of like the zippy component. You'll see in the docks if this sounds familiar.

We'll say, "Model title," and then, the title in here will be, "Model Title." I guess we can do this is...I'll just do some content in here. We'll say, "This is the model content." All content. We'll have two fields, title content and they are not hooked up at all yet.

So, let's start working on that. Here, the title is coming in through an attribute. We can do the shortcut here. I'm just doing a scope. We are going to need to restrict the scope or isolate the scope, anyway, since it's more of a component.

We'll say, title is "@" sign and then, we can just wrap this with a div. Let's get fancy here. Wrap this with a div, and this will be our title. Bind to title. That's going to be this incoming title from the scope.

So this should say, "Title," which is bound now. Actually, let's change this where we can wrap this with something like a H3, give it more of a "title-ly" effect. Our main title, perfect. Now, we have a title. We also have some content in here.

Now, what we're going to do is we're going to set up a click on the title. I'll say, let's do ng-click here. We'll say, "Toggle content." In our link function, we can do, "Scope," "Toggle content," in this via function that will hide and show the content whenever we click on it. We'll set up something called, "Scope is content visible."

Sure, that works for me. We'll say, "Scope is content visible = the flip of it." So from here, we're going to say in our content, "ng-show is content visible," and see where we are at here.

This is our title, click on this, it will show and hide the content, but the content should really be coming from here, which is not happening. That's because we haven't set up transclusion, because, again, transclusion is when you take the content of an element and yank it out and then, put it back into somewhere else inside of your directive.

We'll say, "Transclude is true." Then, we can drop our transclusion into here. Just say, "ng-transclude."

We don't need that "Hello, world," in there anymore. From here, this is the title. This is content. Click on this, you'll say, "World, this is content." You can see it's bound right here. There, I left in "world." There, I left in content. So I can say, "The content is."

Title time, content time, click on the title. The content is, content time, click on it again, hide/show. Content is bound, and title is bound. That's kind of the basics of a zippy component. We used things like to get and create an element, bringing in the title from the attribute here, transcluding the content, and then, bringing that in through ng-transclude right here.

Let's look at this, a bit cleaner. This will look something more like this. From here on out, that's pretty much all we have to do is we just show and hide the content, by when you click on it, toggle that flag right there, and you have yourself a zippy.

You could style it to make...we could look more like a zippy, but I'm not going to worry about styling for now. Anything else to show?

One thing to mention is that, because this is transcluded, this expression model content is being evaluated in the scope of its parent. Even though we've isolated the scope here, you would think, "Oh, I shouldn't be able to access the model content, because I isolated the scope."

It's important to note that the content that's transcluded is, actually, evaluated in the parent scope. So this has access to this, and then, just gets brought in, and elevated and provided into there as the string.

That's pretty much it. Hopefully, that makes sense. We'll start building some more advanced components as we go along.

Joel's Head
Why are we asking?