September 29, 2015

Named ui-views with AngularJS, ui-router and ui-bootstrap

Tipps and Tricks

In one of my last tasks I have had the necessity of adapting a section of a single page application (SPA), in order to get ui-router and ui-bootstrap (plus Bootstrap CSS) work together.

In this article I will shortly share with you the result of my experience, by showing how to improve the coexistence of AngularJS, ui-router and ui-bootstrap via some “tricks” that can ease the creation and maintenance of your single page applications.

In particular, I will discuss how to manage the advanced injection of content in multiple views and, at the same time, how to handle the navigation within the application via the State Provider of ui-router. Such elements are not distant from what also the ui-router official guide describes and are aspects that you would need when switching from a basic to an advanced usage of the tool.

At the end of the article you will find a working example, containing what I will describe in the next paragraphs. I suggest you to firstly read the description, in order to understand the details of the example.

Let’s Go with ui-router

As is generally known, ui-router doesn’t comes bundled in AngularJS, instead it’s a separate tool that you can integrate in you project. The same for ui-bootstrap. In the following description I will presume that you are already able to move your first steps with both those libraries and that you know (more or less) the elements on which they are based on (for a good starting point to learn ui-router I suggest you this video).

Theory apart, the minimal set of elements that you need, to catch the meaning of the suggestions I want to share with you, is:

  • An index.html page that you would use as starting point of your SPA (i.e. as container for some menu entries)
  • An Angular Module where to inject the ui-router and ui-bootstrap dependencies
  • A Controller for the index.html
  • A Config for your App where you can define each state’s behavior

Now, what you would normally do, in order to define the states associated with each menu entry is:

This would let you simply navigate between the states with your index’s buttons, while:

  • ui-router injects the active state’s view in the <div ui-view></div> of the index.html,
  • activates the state’s controller
  • (eventually), pre-resolves data.

Obviously, being that each state’s template contains its own <div ui-view></div>, you can easily create some sub-states (i.e., tabs.list or content.submenu) and inject them, in turn, in the related parent’s state. This is wonderful! This is what ui-router, basically, has been designed for!

But, what if we would want/need to have a more complicated situation, with multiple views, injected within other views and, at the same time, parallel views one next to another? (click here to go to the mockup)

Example of parallel and nested multiple views

Multiple named views and abstract states

Multiple named views

The solution comes with ui-router itself, under the name of (multiplenamed views. In practice, instead of just decorating a state with a single view (and a controller) we consider a state as, potentially, made of many views. Each view will be identified via its own name and will have its own controller (and data). The views will live within their state, being therefore activated when the navigation “wakes” the state (per /url, per $state.go or per ui-sref ).

This perspective is something like (1 state)-to-(n views). What ui-router enables is also (1 ui-view)-to-(n states). This means that you can control which view, from which state will be injected in which ui-view. This lets you injecting each view within each other, creating complex structures with substructures.

From theory to practice: all it’s based upon 3 elements:

  • A name for the ui-view (you need it to identify where to inject your view)
  • The state in which the view that contains the ui-view is defined
  • The definition of the NAME of each view (which controls everything)

The name of each view is made of: theNameOfTheTargetUiView@theNameOfTheState.ThatContainsThe.UiView.

In other words, you can use the name of the view to define where (in terms of state and ui-view) the view itself will be injected. You can think at this namespace as a way to define the routes of your application and to attach each of them to your SPA’s workflow.

Abstract states

Another element that I suggest you to use, when working with multiple ui-routes, is the definition of proper abstract states. These are states that you can’t directly access, but only navigate through. Those are perfect for data pre-resolution or for global element’s definition. An example of that can be the following definition of a set of bootstrap’s Tabs for our sample application:

  • The view of the abstract state (/tabs.tpl.html):
  • And the related state’s definition:

This way, each tab (say tabs.first and tabs.second) will have the skeleton of the abstract state as template and they will “live” within the parent’s ui-view=”tabs”.

Then, we need to define the content of each tab: for this purpose we use the multiple named view system of the previous paragraph! I will omit the rest of the code I want to share with you, because it would be too long for the article, but you can find it in the following Plunker.

Notice, in the app.js file how each state contains one or more named views and how each named view is injected in the ui-view declared in its name.

…another small hint

Please consider the code in the Plunker, if you navigate to the “Example Tabs” and then click on the “Content tab” you will see a “Replace Content” button. If you click it, you may notice that the content gets replaced with another and that you can undo this operation by clicking “Go Back”. This is reachable via ui-router and the multiple named views, simply by using the same ui-view with two different views of two distinct states. In this example, within the app.js, the “left_inside_secondTab@tabs.second” of “tabs.second.content” and the “left_inside_secondTab@tabs.second” of “tabs.second.content.replace”.

Related Posts

Admin Admin
Developer at thecodecampus </>

One response to “Named ui-views with AngularJS, ui-router and ui-bootstrap”

  1. Mahdi says:

    Thanks for your article
    I have a problem in multi tab state. When I change tab $scope of controller rest and initiate, how can prevent $scope state when change tab and state

Leave a Reply

Add code to your comment in Markdown syntax.
Like this:
`inline example`

code block

Your email address will not be published.