The ui-router library for AngularJS provides the ability to name views within your application. This is useful for dividing up your application into sections, and changing the content of a section based on the current state.
Joel Hooks: Our application has several actions. It has a header, it has a sidebar that's going to contain navigation, it has a content area and a footer.
The header and footer are areas that we probably want to reuse across our application, while the sidebar and the content might change based on the current state we're in.
If we're using AngularJS default routing you might have to resort to something like ng-include to get that sort of reuse with your headers and footers. Even then, it's not providing the most flexible solution.
We're going to use ui-router to build a simple application that utilizes these four sections.
With ui-router imported into our application, the next thing we need to do is create a config function. The config function injects the state provider, which is a provider that UI router gives us that we can use to define our states.
Our first state we're simply going to call app, and we're going to give it a URL of /, meaning it's going to be the root of our application.
The next thing you'll notice on the state is a views property. This views property is an object, and it's going to contain our various sections and name them accordingly and associate them with a template URL.
The first name view we're going to define is our header. We give it a name of header, and this is in our common templates folder.
The next view we want to define is our sidebar.
Then we'll define our main content area.
Finally we'll define our footer.
With our named views defined on our state, the next thing we need to do is update our markup so that ui-router knows where to find those view elements.
This is our root state and we're going to find those elements in our index.HTML.
We're going to use the ui-view attribute that's provided by ui-router to give this ui-vew a name. We'll call it header.
Immediately you'll notice that our view actually updates with this header that we've defined. We'll come over here and look at the markup for that. You can see it's just a simple div with a heading of routing with named views.
Now we just need to add the ui view for our sidebar, for our content, and of course our footer.
Do notice that this updates our page with the header, the content area, the sidebar navigation, as well as our footer.
The real power of ui-router's named views comes when we want to change out individual areas of our content or individual sections.
If we want to change out the content itself and have that based on a particular state, it's pretty easy to do.
We're going to come over here to alt1. This is the first alternative state that we're going to define and replace those named views.
Our alt1 module needs to have state defined. If we navigate we'll notice that it doesn't actually go anywhere. There's no state defined and the link doesn't work.
I'm going to define a state and I'm going to call it app.alt1.
We're using the dot notation to tell the state provider that this is actually a substate of the root app state.
We're going to give it a URL of alt1.
Now we need to define some named views for our alternative state. In our alt1 state, we're going to override the content view.
You'll quickly notice that this isn't actually updating our content. We can get to our state, but it's not replacing the content of the view.
This is because we need to use the @ sign after content to let ui-router know that we want to override the named view content, @. Since we didn't put anything after this, it's going to actually look at the root of our application or the root state. It's going to come back here, look at app, and find the content view to replace.
Now we notice that when we come to one, our alternative content shows up. This is the content of the template file for the alt1 module.
With ui-router's named views, we're actually able to override any and/or all of the templates in our named views.
In this case, we're going to override the header. Again, we need to use the @ sign to tell ui-router where it's located.
Now we'll navigate to our alt2 module. You'll notice that we've replaced the header as well as the content.
Another feature of named views and ui-router, in general, is the ability to nest your views.
In this case, we're going to look at our alt3 module. In the content, we're actually going to add two named views within the content area of our state. We'll come over here. We need to define those views. Our first view is named one, and we're going to use the @ notation here, and we need to point it to app.alt3, which is the name of the module we're currently in.
What this is going to do, previously we'd use the @ sign with nothing and it would go look at the root state. In this case we're going to look for a named view called one at the app.alt3 state, which is our current state. It'll look within this state, find that named view and replace it with our content.
We're not going to use an external template for this. I'm just going to make a little div.
You'll see our first named subview is within our content area. I'm just going to copy this real quick. Have it look for our two view. You'll see our view update with our two named subviews.
This is something you kind of want to use with caution. If you get too crazy with it and you have nested views that go too deep, it can get confusing and might be hard to follow for yourself or other developers.
Use this with caution. It's a powerful tool, but with great power comes great responsibility.