Building a demo AngularJS directive named Zippy using ng-model, ng-click and transclusion (no controller)
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.