路由 Route
我在 慕課網 學習 AngularJS
為什么用 Route
-
AJAX 請求不會留下 History 記錄
-
用戶無法直接通過 URL 進入應用中的指定頁面(保存書簽、鏈接分享給朋友)
-
AJAX 對 SEO 是個災難
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', constoller: '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
以上方法為查看當前狀態是否在某父狀態內,比如 $state.includes('contacts')
返回 true
/ false
<!-- 包含在 /contacts 狀態內部,即其作為 parant state -->
<li ng-class="{active: $state.includes('contacts')}">
<a ui-serif="contacts.list">Contacts</a>
</li>
ui-sref-active 查看當前激活狀態並設置 Class
<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>',
// optional below
templateProvider: ['$timeout',
function($timeout) {
return $timeout(function() {
return '<p class="lead">UI-Router Resource</p>' +
'<p>The second line</p>'
}, 100);
}
],
templateUrl: 'about.html',
templateUrl: function() {
return 'about.html';
},
controller: 'UIRouterCtrl',
// below is a state controller picked from UI-Router official sample
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 });
}
}
]
});
嵌套配置 Configure
JavaScript Codes
Parent Router
$stateProvider.
.state('contacts', {
// abstract: true 表明此狀態不能被顯性激活,只能被子狀態隱性激活
abstract: true,
url: '/contacts',
templateUrl: 'contacts.html',
// resolve 被使用來處理異步數據調用,以下是返回一個 promise -> contacts.all()
resolve: {
contacts: ['contacts',
function(contacts) {
// 以下方法被放在 contacts.service.js 中,以 factory 存在
return contacts.all();
}
]
},
// below is a state controller picked from UI-Router official sample
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 (Nested Router)
$stateProvider
.state('contacts.list', {
url: '',
templateUrl: 'contacts.list.html'
})
.state('contacts.detail', {
url: '/{contactId:[0-9]{1,4}}',
// view 用在該狀態下有多個 ui-view 的情況,可以對不同的 ui-view 使用特定的 template, controller, resolve data
// 絕對 view 使用 '@' 符號來區別,比如 'foo@bar' 表明名為 'foo' 的 ui-view 使用了 'bar' 狀態的模板(template),相對 view 則無
views: {
// 無名 view
'': {
templateUrl: 'contacts.detail.html',
controller: ['$scope', '$stateParams', 'utils',
function ($scope, $stateParams, utils) {
$scope.contact = utils.findById($scope.contacts, $stateParams.contactId);
}
]
},
// for "ui-view='hint'"
'hint@': {
template: 'This is contacts.defail populating the "hint" ui-view'
},
// for "ui-view='menuTip'"
'menuTip': {
templateProvider: ['$stateParams',
function($stateParams) {
return '<hr><small class="muted">Contact ID: ' + $stateParams.contactId + '</small>';
}
]
}
}
})
HTML Codes
<h2>All Contacts</h2>
<ul>
<li ng-repeat="contact in contacts">
<a ui-sref="contacts.detail({contactId:contact.id})">{{contact.name}}</a>
</li>
</ul>