ui-router's states and AngularJS directives have much in common. Let's explores the similarities between the two and how these patterns have emerged in Angular. Keeping your states and directives consistent can also help with refactoring as your app grows larger over time.
You might be surprised how similar states and directives are. For example, let's set up a state here. We'll inject our state provider and say stateprovider.state. I'll call this state our home and then pass in our configuration object. On this we'll have a controller which we'll call home controller as home. Then we'll have a template URL which we'll call template/home.html.
Now if we go ahead and set up a directive, and we'll name this something like app header, we'll have this return to configuration object which has a controller, which we'll call app header controller as app header and a template URL which we'll call template/appheader.html.
Already you can see this concept emerging where we have a controller on a directive. We have a controller on our state and a template on both of them as well. This idea and these concepts have evolved and emerged in Angular where everything has a controller and everything has a template. The two pair together, and then you use the controller as syntax to reference your controller inside of those templates.
We'll go ahead and set up some super basic templates, so templates/home.html. We'll say H1 home template and DIV. This is some content. The only thing we have to do to make this work is give it a URL which we'll set to nothing for now. We'll refresh, and we'll get our template showing up.
We'll go ahead and set up our home controller, home controller. Our home is this, and we'll just put some content which will say, "Content from the controller." Now on our home template instead of "this is some content" it can say "home.content" and refresh. You'll see we have the content now coming from the controller.
We can take the exact same approach in our directive, and we'll create an app header template, appheader.html. We'll just drop an H2 in there with a binding to appheader.content. Switch back over to this [inaudible 2:47] controller. Call it app header controller. Our app header is this and appheader.content is header content from the controller.
Then I'll go ahead and just drop our app header inside of our home template, refresh, and you can see we have our header from our directive, and the content from the controller, and then everything else from our template.
What we can see now is that our controllers are pretty much exactly the same in the way that we set them up and configure them. Our directive configuration object here is pretty much the same as our state provider configuration object here.
One difference that you can notice is that we do have a function here wrapping around this return statement. Now that using a controller is more common place this could actually go away, but I don't see that happening anytime soon.
The other idea or concept which is very similar is using state params to pass in data from the URL and scope to pass in data through attributes on the element. The pattern that we've really seen emerge here is defining a configuration for your state from the state provider, having a controller handle all of the code and the APIs for the different services you're going to access, and then just dropping everything in your template to design what that state looks like.
Those exact same ideas apply to directives as well, where this is your configuration on how to set up your directive, this is all of your code and APIs to access services, and this is just your template. What this means is that if you have a directive that you think is getting too big or too much for just a component, it could easily evolve and grow into a state. Or if you have a state which you think is too small for taking up an entire view, you could shrink that down into a directive component.