Angular-UI-Router 学习笔记
路由 (Route)
为什么用 Route
- AJAX 请求不会留下 History 记录
- 用户无法直接通过 URL 进入应用中的指定页面(无法保存书签、链接分享给朋友)
- AJAX 对 SEO 是个灾难
AngularJS 路由配置示例
var bookStoreApp = angular.module('bookStoreApp', [
'ngRoute',
'ngAnimate',
'bookStoreCtrls',
'bookStoreFilters',
'bookStoreServices',
'bookStoreDirectives'
]);
bookStoreApp.config(
function($routeProvider) {
$routeProvider
.when('/hello', {
templateUrl: 'tpls/hello.html',
controller: 'HelloCtrl'
})
.when('/list/:bookId', {
templateUrl: 'tpls/bookList.html',
controller: 'BookListCtrl'
})
.otherwise({
redirectTo: '/hello'
});
}
);
嵌套 View (Nested Routing for AngularJS)
AngularUI-Router (AngularUI)
<div ui-view></div>
前端路由的基本原理
- 哈希 (#)
- HTML5 中新的 history API
- 路由的核心 是给应用定义 "状态"
- 使用路由机制会影响应用的整体编码方式 (需预先定义好状态)
- 考虑兼容性问题与 "优雅降级"
Angular-UI-Router
ui-sref 指令
<a ui-sref="home">Home</a>
<a ui-sref="about">About</a>
<a ui-sref="contacts.list">Contacts</a>
$state.includes 返回 true / false
<li ng-class="{active: $state.includes('contacts')}">
<a ui-serif="contacts.list">Contacts</a>
</li>
ui-sref-active
<li ui-sref-active="active">
<a ui-sref="about">About</a>
</li>
包含模块
angular.module('uiRouter', ['ui.router']);
方便获得当前状态的方法 (绑到根作用域)
app.run(['$rootScope', '$state', '$stateParams',
function($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}
]);
路由重定向 ($urlRouterProvider)
app.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.when('/c?id', '/contacts/:id')
.when('/user/:id', '/contacts/:id')
.otherwise('/');
}
]);
状态配置
$stateProvider.
state('about', {
url: '/about',
template: '<h1>Welcome to UI-Router Demo</h1>',
// 使用 templateProvider 处理异步加载
templateProvider: ['$timeout',
function($timeout) {
return $timeout(function() {
return '<p class="lead">UI-Router Resource</p>' +
'<p>The second line</p>';
}, 100);
}
],
templateUrl: 'about.html',
controller: 'UIRouterCtrl',
controller: ['$scope', '$state', 'contacts', 'utils',
function ($scope, $state, contacts, utils) {
$scope.contacts = contacts;
$scope.goToRandom = function () {
var randId = utils.newRandomKey($scope.contacts, 'id', $state.params.contactId);
$state.go('contacts.details', { contactId: randId });
}
}
]
});
嵌套路由 (Nested Router)
父级路由 (Parent Router)
$stateProvider.
state('contacts', {
abstract: true,
url: '/contacts',
templateUrl: 'contacts.html',
// 处理异步数据调用
resolve: {
contacts: ['contacts',
function(contacts) {
return contacts.all();
}
]
},
controller: ['$scope', '$state', 'contacts', 'utils',
function ($scope, $state, contacts, utils) {
$scope.contacts = contacts;
$scope.goToRandom = function () {
var randId = utils.newRandomKey($scope.contacts, 'id', $state.params.contactId);
$state.go('contacts.details', { contactId: randId });
}
}
]
});
子级路由 (Children Router)
$stateProvider
.state('contacts.list', {
url: '',
templateUrl: 'contacts.list.html'
})
.state('contacts.detail', {
url: '/{contactId:[0-9]{1,4}}',
views: {
// 默认 view
'': {
templateUrl: 'contacts.detail.html',
controller: ['$scope', '$stateParams', 'utils',
function ($scope, $stateParams, utils) {
$scope.contact = utils.findById($scope.contacts, $stateParams.contactId);
}
]
},
// 其他 view
'hint@': {
template: 'This is contacts.detail populating the "hint" ui-view'
},
'menuTip': {
templateProvider: ['$stateParams',
function($stateParams) {
return '<hr><small class="muted">Contact ID: ' + $stateParams.contactId + '</small>';
}
]
}
}
});
HTML 代码
<h2>All Contacts</h2>
<ul>
<li ng-repeat="contact in contacts">
<a ui-sref="contacts.detail({contactId:contact.id})">{{contact.name}}</a>
</li>
</ul>
评论