AngularJS Architecture: Using ui-router's named views

Lukas Ruebbelke
InstructorLukas Ruebbelke

Share this video with your friends

Send Tweet
Published 8 years ago
Updated 4 months ago

We'll take a deeper look at ui-router as we introduce named views into Eggly. We will take the basic state that we defined in the previous video and refactor it so that it consists of two unique views within the application.

[00:00] In this lesson, we are going to really tap into the power of ui-router with named views. In the previous lesson, we created a single, simple route and moved our main layout into an HTML template.

[00:16] We are going to take that a step further by separating that template into two templates, a category template and a bookmarks template, and then defining a separate view for each of them.

[00:28] When working with a large application, it is often a good idea to define a top-level, abstract state that defines the base layout, as well as any additional information that you want the child states to draw from.

[00:46] Let's take a quick moment and refactor the Eggly state to be an abstract state that we can use as a starting point for the additional states that we're going to define. We're also going to set up a fallback to redirect the user with one additional service called "urlRouterProvider."

[01:10] I am going to inject urlRouterProvider, and then from here, we're just going to say, "Abstract is true." I'm going to say, "Otherwise, just redirect to the root of the application."

[01:42] Now that we've done that, let's refactor our categories template that just contains everything here into two specific templates. In categories, I'm going to just copy this right here, and I'm going to paste this up here.

[02:05] Then, for the bookmarks, I'm going to copy the bookmark-specific stuff, and I'm going to paste this into the bookmarks template.

[02:22] Now, we are left with this remaining container HTML. We are going to go back into our main HTML file and paste this into here. Let's delete this unnamed ui-view here, and let's create two named views.

[02:44] This is where we want the categories to go. We're going to go ui-view. This takes a property here of categories, and then let's do the same for bookmarks, ui-view.

[03:02] Now that we have named ui-views, we need to define corresponding views and our stateProvider to match up. We'll hop into our categories and define an Eggly category state that we can attach our views to.

[03:20] We will inject our stateProvider.

[03:45] We will give this the URL of the root of the application, and then we are going to define our views property. This is going to be just an empty object initially, but we need the keys on the views object to match up to our named view, so categories and bookmarks.

[04:08] We'll go categories.

[04:21] We are adding the at symbol to make this an absolute path, meaning that it will target this named view specifically with any unnamed state within our main page.

[04:34] This allows us to go as far as defining specific configurations or a specific view and a specific state. More on that later. From here, it's pretty much like defining a normal route. We will define our controller and template URL, and we should be ready to go.

[04:55] We will do the same for our bookmarks.

[05:47] The categories controller and the bookmarks controller doesn't actually exist yet, so let's just define just a real quick stub of those. We'll go controller.

[06:14] Let's do the same for the bookmarks controller.

[06:30] We should be good to go. Let's go back into the browser and refresh. You can see that the page is still rendering, but if we actually inspect the element here, we can see that it's actually targeting the categories ui-view and the bookmarks ui-view.

[06:57] Just a quick recap. We refactored the Eggly state to be abstract, as well as we introduced urlRouterProvider to redirect to the root of the application.

[07:12] We then refactored the categories template, or the main template, to have two separate templates, categories and bookmarks, and then, in the main index page, we introduced two ui-views, ui-view categories, ui-view bookmarks.

[07:30] Then, from here, we defined the eggly.categories state with the URL of the root of the application and then two absolute views targeting the categories named view, the bookmarks named view, and the controller and the template for each of those views.

[07:51] I look forward to seeing you in the next lesson, where we are going to introduce stateParams so we can pass specific information from one state to another. See you then.

James
James
~ 8 years ago

So, I get that a lot of people wonder how to handle sub views and the like in angular, but is this not what directives and transclusion are for? I know that for many people directives are the 'hardest' part of angular to learn but as a teaching resource would it be better to point people to directives as a solution to their problem?

Im just curious about the decision process for using ui-router for this feature? (Its better then ng-route just because of the ui-serf function but Im not sold on named views).

Nice demo though :) Keep up the good work.

Joel Hooks
Joel Hooks
~ 8 years ago

ui-routers #1 flaw IMO is the debugging. It fails silently providing no context for debugging. If a view is specified, but no matching target is found, it doesn't say a word!

These errors are almost always a missing ui-view or there is a string with a typo someplace.

Regardless, it is impossible to debug this without the code in context!

Guillaume Leclerc
Guillaume Leclerc
~ 8 years ago

Question. I have almost the same setup, a main app with submodules, I use ui.router in all the submodules. But I couldn't make it work initially, I had a loading module error from Angular. I was able to solve it by putting ui.router as the first dependency in the main module. But I don't understand why it works. If I put my submodules first and ui.router after in the main module, then I have to redefine the ui.router dependency in my submodules. If I put ui.router first, then I don't need. I'm surprised. I'm sure I'm missing something simple here, any idea? Thanks!

Paul Mark Quinn
Paul Mark Quinn
~ 7 years ago

It was bizarre for me in that, it would only work after I actually removed abstract and url from the base module state config:

.config(function ($stateProvider, $urlRouterProvider) { $stateProvider .state('eggly', { //url : '/', //abstract : true }) ;

  $urlRouterProvider.otherwise('/');

})

~ 7 years ago

Good call. Same situation here. The commenting out worked.

Aaron Endsley
Aaron Endsley
~ 6 years ago

Im getting an injector error saying $urlRouteProvider

Aaron Endsley
Aaron Endsley
~ 6 years ago

Ha Ha Never Mind I Mistyped its supposed to be $urlRouterProvider