Angular 1.x directives for declarative state navigation and view rendering in templates. UI-Router provides several directives that enable template-based interaction with the routing system.
Viewport directive that renders views from active states. Acts as a placeholder where state views are dynamically inserted.
/**
* uiView directive for rendering state views
*/
interface UiViewDirective {
/** Optional view name for targeting specific views */
name?: string;
/** Auto-scroll behavior when view is activated */
autoscroll?: boolean | string;
/** Expression evaluated when view updates */
onload?: string;
}Usage Examples:
<!-- Unnamed view (default) -->
<div ui-view></div>
<!-- Named view -->
<div ui-view="content"></div>
<!-- Alternative named view syntax -->
<ui-view name="sidebar"></ui-view>
<!-- Auto-scroll configuration -->
<div ui-view autoscroll="true"></div>
<div ui-view autoscroll="shouldScroll"></div>
<!-- On-load callback -->
<div ui-view onload="onViewLoaded()"></div>
<!-- Multiple named views in layout -->
<div class="app-layout">
<header ui-view="header"></header>
<nav ui-view="sidebar"></nav>
<main ui-view="content"></main>
<footer ui-view="footer"></footer>
</div>Template Integration:
// State with multiple views
$stateProvider.state('app', {
url: '/app',
views: {
'header': {
template: '<app-header></app-header>'
},
'sidebar': {
templateUrl: 'sidebar.html',
controller: 'SidebarController'
},
'content': {
template: '<ui-view></ui-view>' // Nested ui-view
}
}
});
// Controller with onload handling
angular.module('myApp').controller('LayoutController',
['$scope', function($scope) {
$scope.onViewLoaded = function() {
console.log('View loaded and rendered');
};
$scope.shouldScroll = true;
}]);Creates links to states with automatic URL generation and active state management.
/**
* uiSref directive for state navigation links
*/
interface UiSrefDirective {
/** State name and parameters expression */
uiSref: string;
/** Additional transition options */
uiSrefOpts?: string;
}Usage Examples:
<!-- Basic state link -->
<a ui-sref="home">Home</a>
<!-- State with parameters -->
<a ui-sref="users.detail({ userId: user.id })">View User</a>
<!-- State with query parameters -->
<a ui-sref="search({ query: 'angular', category: 'docs' })">Search</a>
<!-- Link with transition options -->
<a ui-sref="dashboard" ui-sref-opts="{ reload: true }">Refresh Dashboard</a>
<!-- Link with inherited parameters -->
<a ui-sref="users.edit" ui-sref-opts="{ inherit: true }">Edit</a>
<!-- Relative state navigation -->
<a ui-sref=".child">Child State</a>
<a ui-sref="^.sibling">Sibling State</a>
<!-- Dynamic state links -->
<a ui-sref="{{dynamicState}}({ id: item.id })">Dynamic Link</a>
<!-- Links on non-anchor elements -->
<button ui-sref="admin.settings">Settings</button>
<div ui-sref="modal.open" class="clickable-card">Click to Open</div>Advanced uiSref Usage:
<!-- Conditional parameters -->
<a ui-sref="search({ query: searchTerm || undefined, page: currentPage > 1 ? currentPage : undefined })">
Search Results
</a>
<!-- Complex parameter expressions -->
<a ui-sref="user.profile({
userId: user.id,
tab: selectedTab,
filters: filterObject
})">
User Profile
</a>
<!-- Programmatic sref with scope variables -->
<div ng-repeat="item in items">
<a ui-sref="{{item.stateLink}}({ id: item.id })">{{item.title}}</a>
</div>Applies CSS classes when the current state matches the linked state.
/**
* uiSrefActive directive for active state styling
*/
interface UiSrefActiveDirective {
/** CSS classes to apply when state is active */
uiSrefActive: string;
/** CSS classes for exact state match */
uiSrefActiveEq?: string;
}Usage Examples:
<!-- Basic active state styling -->
<a ui-sref="home" ui-sref-active="active">Home</a>
<!-- Multiple CSS classes -->
<a ui-sref="users" ui-sref-active="active highlighted">Users</a>
<!-- Exact state matching -->
<a ui-sref="users.list" ui-sref-active-eq="exact-match">User List</a>
<!-- Combined active and exact matching -->
<a ui-sref="admin"
ui-sref-active="section-active"
ui-sref-active-eq="page-active">
Admin
</a>
<!-- Navigation menu with active states -->
<nav class="main-nav">
<a ui-sref="home" ui-sref-active="nav-active">Home</a>
<a ui-sref="products" ui-sref-active="nav-active">Products</a>
<a ui-sref="about" ui-sref-active="nav-active">About</a>
<a ui-sref="contact" ui-sref-active="nav-active">Contact</a>
</nav>
<!-- Nested state active styling -->
<ul class="sidebar-menu">
<li ui-sref-active="menu-open">
<a ui-sref="users">Users</a>
<ul class="submenu">
<li><a ui-sref="users.list" ui-sref-active="submenu-active">List</a></li>
<li><a ui-sref="users.create" ui-sref-active="submenu-active">Create</a></li>
</ul>
</li>
</ul>CSS Integration:
/* Active state styles */
.nav-active {
font-weight: bold;
color: #007bff;
background-color: #f8f9fa;
}
.exact-match {
border-bottom: 2px solid #007bff;
}
.menu-open > a {
background-color: #e9ecef;
}
.submenu-active {
background-color: #007bff;
color: white;
}Alternative directive for state-based functionality, providing additional state information.
/**
* uiState directive for enhanced state integration
*/
interface UiStateDirective {
/** State reference expression */
uiState: string;
}Usage Examples:
<!-- Alternative to ui-sref -->
<div ui-state="dashboard">Dashboard Section</div>
<!-- State-aware components -->
<div ui-state="users.detail({ userId: user.id })" class="user-card">
<h3>{{user.name}}</h3>
<p>Click to view details</p>
</div>Template filters for state-based conditionals and information.
/**
* State filters for template usage
*/
interface StateFilters {
/** Check if current state is specified state */
isState: (state: string, params?: any, options?: any) => boolean;
/** Check if current state includes specified state */
includedByState: (state: string, params?: any, options?: any) => boolean;
}Usage Examples:
<!-- Conditional content based on current state -->
<div ng-if="'home' | isState">
<h1>Welcome Home!</h1>
</div>
<div ng-if="'users' | includedByState">
<breadcrumb></breadcrumb>
</div>
<!-- State-based styling -->
<body ng-class="{
'home-page': 'home' | isState,
'admin-section': 'admin' | includedByState,
'user-area': 'users' | includedByState
}">
<!-- Menu highlighting with filters -->
<nav>
<a ui-sref="dashboard"
ng-class="{ active: 'dashboard' | isState }">
Dashboard
</a>
<a ui-sref="users"
ng-class="{ active: 'users' | includedByState }">
Users
</a>
</nav>
<!-- Parameter-based filtering -->
<div ng-if="'users.detail' | isState:{ userId: currentUser.id }">
<p>Viewing your own profile</p>
</div>Common patterns for using UI-Router directives effectively.
<nav class="main-navigation">
<ul class="nav-list">
<li class="nav-item">
<a ui-sref="home"
ui-sref-active="nav-active"
class="nav-link">
<i class="icon-home"></i>
Home
</a>
</li>
<li class="nav-item" ui-sref-active="nav-section-active">
<a ui-sref="users" class="nav-link">
<i class="icon-users"></i>
Users
</a>
<ul class="nav-submenu" ng-if="'users' | includedByState">
<li>
<a ui-sref="users.list" ui-sref-active="nav-subactive">All Users</a>
</li>
<li>
<a ui-sref="users.create" ui-sref-active="nav-subactive">Add User</a>
</li>
</ul>
</li>
</ul>
</nav><div class="breadcrumb" ng-if="!('home' | isState)">
<a ui-sref="home">Home</a>
<span ng-if="'users' | includedByState">
> <a ui-sref="users">Users</a>
</span>
<span ng-if="'users.detail' | isState">
> <span>{{user.name}}</span>
</span>
<span ng-if="'users.edit' | isState">
> <a ui-sref="users.detail({ userId: user.id })">{{user.name}}</a>
> <span>Edit</span>
</span>
</div><div class="content-area">
<!-- Loading indicator during state transitions -->
<div ng-if="$state.transition" class="loading-overlay">
<div class="spinner"></div>
<p>Loading...</p>
</div>
<!-- Main content view -->
<div ui-view
autoscroll="true"
onload="onContentLoaded()"
class="main-content">
</div>
<!-- State-specific sidebars -->
<aside ng-if="'dashboard' | isState" class="dashboard-sidebar">
<widget-list></widget-list>
</aside>
<aside ng-if="'users' | includedByState" class="users-sidebar">
<user-filters></user-filters>
</aside>
</div><!-- Modal backdrop -->
<div ng-if="'modal' | includedByState"
class="modal-backdrop"
ui-sref="^">
</div>
<!-- Modal content -->
<div ng-if="'modal.confirm' | isState" class="modal">
<div class="modal-content">
<h3>Confirm Action</h3>
<p>Are you sure you want to proceed?</p>
<div class="modal-actions">
<button ui-sref="^" class="btn btn-cancel">Cancel</button>
<button ng-click="confirm()" class="btn btn-primary">Confirm</button>
</div>
</div>
</div>
<!-- Overlay with nested view -->
<div ng-if="'overlay' | includedByState" class="overlay">
<div class="overlay-content">
<button ui-sref="^" class="close-btn">×</button>
<div ui-view="overlay"></div>
</div>
</div>Common directive usage errors and solutions:
<!-- ERROR: Missing quotes around state expression -->
<a ui-sref=home>Home</a>
<!-- CORRECT: Quoted state expression -->
<a ui-sref="home">Home</a>
<!-- ERROR: Invalid parameter syntax -->
<a ui-sref="users.detail(userId: user.id)">User</a>
<!-- CORRECT: Object parameter syntax -->
<a ui-sref="users.detail({ userId: user.id })">User</a>
<!-- ERROR: Missing ui-view for state content -->
<div class="content">
<!-- State content won't render without ui-view -->
</div>
<!-- CORRECT: Include ui-view for content -->
<div class="content">
<div ui-view></div>
</div>Debugging Tips:
<!-- Debug current state information -->
<div class="debug-info" ng-if="debugMode">
<p>Current State: {{$state.current.name}}</p>
<p>State Params: {{$state.params | json}}</p>
<p>Transition: {{$state.transition ? 'In Progress' : 'None'}}</p>
</div>
<!-- Validate state existence -->
<a ng-if="$state.get('target.state')"
ui-sref="target.state">
Valid Link
</a>
<span ng-if="!$state.get('target.state')" class="error">
Invalid state: target.state
</span>