UI-Router is a powerful and flexible routing library for AngularJS that allows for more advanced routing features compared to the built-in $routeProvider
. One of its most prominent features is nested routes, which allows you to manage complex applications with multiple views and nested states.
In this guide, we will walk through how to implement nested routes using UI-Router in an AngularJS application, step by step.
1. Setting Up UI-Router
To begin using UI-Router, you need to include the library in your AngularJS project. UI-Router works by managing states instead of routes, making it suitable for complex, nested view management.
Step 1: Install UI-Router
Add the UI-Router script to your project by including it in the index.html
file. You can use a CDN or download the library:
<script src="https://cdnjs.cloudflare.com/ajax/libs/ui-router/1.0.22/angular-ui-router.min.js"></script>
Step 2: Include UI-Router in Your AngularJS Application
Make sure to include the UI-Router module in the dependencies of your AngularJS application:
var app = angular.module('myApp', ['ui.router']);
2. Defining States and Nested Views
UI-Router works by defining states, each of which can have its own URL, controller, and template. You can also define nested states, which will allow you to load different views in different sections of the page. These are called nested routes.
Step 3: Configure UI-Router States
In UI-Router, instead of using $routeProvider
, you use $stateProvider
to define states. Nested views are defined within a parent state.
Here’s how to set up a simple nested route structure:
Example:
- Parent State:
home
- Child State:
home.dashboard
,home.profile
app.config(function($stateProvider, $urlRouterProvider) {
// Default Route
$urlRouterProvider.otherwise('/home');
// Define States
$stateProvider
// Parent State
.state('home', {
url: '/home',
templateUrl: 'home.html', // The main template for the 'home' view
controller: 'HomeController',
// Nested Views (children)
views: {
'content@': {
templateUrl: 'home-content.html' // Parent's default view
},
'sidebar@': {
templateUrl: 'sidebar.html' // A sidebar for the home page
}
}
})
// Nested Child State: home.dashboard
.state('home.dashboard', {
url: '/dashboard',
templateUrl: 'dashboard.html', // Template for dashboard
controller: 'DashboardController'
})
// Nested Child State: home.profile
.state('home.profile', {
url: '/profile',
templateUrl: 'profile.html', // Template for profile
controller: 'ProfileController'
});
});
3. Explanation of the State Configuration
- Parent State (
home
):- The
home
state has its owntemplateUrl
andcontroller
. This acts as the main container where nested views will be injected. - The
views
object is where you define nested views. For example, thecontent@
view will load into the main content area, and thesidebar@
view will load into a sidebar.
- The
- Nested States:
- The
home.dashboard
andhome.profile
states are nested under the parenthome
state. - These nested states have their own specific templates and controllers, which will be injected into the views defined in the parent state.
- The
4. Creating HTML Templates
Here’s an example of what the HTML templates might look like for the parent and child states.
home.html (Parent Template)
<div class="main-container">
<div class="content">
<div ui-view="content"></div> <!-- This is where the child views will be injected -->
</div>
<div class="sidebar">
<div ui-view="sidebar"></div> <!-- Sidebar content -->
</div>
</div>
In this home.html
template:
- The
ui-view="content"
is the placeholder for child views such ashome.dashboard
andhome.profile
. - The
ui-view="sidebar"
is used for injecting the sidebar template.
home-content.html (Child Template for Home)
<div class="home-content">
<h1>Welcome to the Home Page!</h1>
<p>This is the main content of the home page.</p>
</div>
sidebar.html (Sidebar Template)
<div class="sidebar">
<h3>Sidebar</h3>
<ul>
<li><a ui-sref="home.dashboard">Dashboard</a></li>
<li><a ui-sref="home.profile">Profile</a></li>
</ul>
</div>
- The
ui-sref="home.dashboard"
directive is used to generate links for navigating between the nested states.
dashboard.html (Child Template for Dashboard)
<div class="dashboard">
<h2>Dashboard</h2>
<p>This is the dashboard view for the home page.</p>
</div>
profile.html (Child Template for Profile)
<div class="profile">
<h2>User Profile</h2>
<p>This is the profile view for the home page.</p>
</div>
5. Controllers
For each state, you can define specific controllers to handle logic for that state.
HomeController
app.controller('HomeController', function($scope) {
$scope.message = 'Welcome to the Home Page!';
});
DashboardController
app.controller('DashboardController', function($scope) {
$scope.message = 'Welcome to your Dashboard!';
});
ProfileController
app.controller('ProfileController', function($scope) {
$scope.message = 'This is your Profile!';
});
6. Using $state
and $stateParams
for Navigation
You can programmatically navigate between states using $state
and pass parameters with $stateParams
. For example:
Navigating Programmatically:
app.controller('HomeController', function($state) {
// Navigate to the dashboard state programmatically
$state.go('home.dashboard');
});
Using $stateParams
to Access Parameters:
If your state has parameters (like /home/:id
), you can access them in your controller:
app.controller('ProfileController', function($scope, $stateParams) {
$scope.userId = $stateParams.id; // Access the 'id' parameter
});
7. Advantages of Nested Routes in UI-Router
- Modularity: Allows you to break down complex layouts into smaller, manageable components.
- Reusability: Components like sidebars or footers can be reused in multiple views without duplication.
- Dynamic View Rendering: You can dynamically change parts of the UI based on nested states, without needing full page reloads.
- Seamless Transitions: Nested views provide a seamless experience for users as they can transition between different sections of an application without reloading the page.