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.
Our application has several sections. 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 as 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. We're going to give it a URL of forward slash, 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, name them accordingly, and associate them with a template URL.
The first named view we're going to define is our header. We give it a name of header, and this is in our common templates folder. 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-View a name. We'll call it header, and 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.
You'll 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 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 to here alt one. This is the first alternative state that we're going to define, and replace those named views.
Our alt one module needs to have a 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.altone.
I'm using the dot notation to tell the state provider that this is actually a sub state of the root app state. We're going to give it a URL one alt one. Now, we need to define some named views for our alternative state.
In our alt one 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 at.
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 alt one module.
With UI-Router's named views, we are 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 alt two module, and 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 reviews. In this case, we're going to look at our alt three 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, and we need to define those views. Our first view is named one. We're going to use the @ notation here, and we need to point it to app.altthree, 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.altthree 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 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. It 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.