ui-router
所谓的Single Page Application (SPA)的核心就是用ui-router来切换不同的UI state,从而实现页面功能。但是相关库并不在AngularJS中,有两个库用的比较多
- ngRouter from Google and community
- ui-router from community
本文基于后者。
How to use it?
<script src="lib/angular.min.js"></script><script src="lib/angular-ui-router.min.js"></script><ui-view></ui-view>angular.module('App',['ui.router']);
ui-router会用template html来替换ui-view标签<ui-view></ui-view>
。
进入核心配置:
angular.module('App').config(RoutesConfig);RoutesConfig.$inject =['$stateProvider', '$urlRouterProvider'];function RoutesConfig($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/view1'); $stateProvider .state('view1', { url: '/view1', template: '<div>…</div>' }) .state('view2', {...});}
$urlRouterProvider.otherwise
设置了默认的URL。$stateProvider
设置了各个状态。
$stateProvider.state('itemDetail', { url: '', templateUrl: '', controller: 'ItemListController as itemList', resolve: { }
每个状态都可以有template和controller。
controller
controller成员有这么几种写法:
- controller: ‘CtrlName as label’
- controller: CtrlName
- controllerAs: label
resolve
The resolve property is a map object. The map object contains key/value pairs of:
- key – {string}: a name of a dependency to be injected into the controller.
- factory - {string|function}:
- If string, then it is an alias for a service.
- Otherwise if function, then it is injected and the return value is treated as the dependency. If the result is a promise, it is resolved before the controller is instantiated and its value is injected into the controller.。
Yaakov的课程此处可能有错讹。并不是什么都能往resolve里放,放数字会报错,具体可参看GitHub - angular-ui/ui-router
也就是factory只有两种可能,string或者function,如果直接放数字,会出错。resolve成员会在controller实例化之前被确定。如果promise被reject,则会取消状态切换,然后错误会被送到$stateChangeError。resolve的成员,通过inject可以被controller使用,如下:
View1Ctrl.$inject = ['myData'];function View1Ctrl(myData) { var view1 = this; view1.myData = myData;}
URL Parameters
.state('view1', { url: '/view1/{param1}', templateUrl: 'view1.html', controller: 'View1Ctrl as view1', resolve: { myData: ['$stateParams', function ($stateParams) { return getDataBasedOn($stateParams.param1); }] }});
这是最正常的写法。在HTML中如下使用:
<a ui-sref="view1({itemId:someVal})"> Link to view with data</a>
或者
$state.go('contacts', {param1: value1})
正则参数
Examples:
/user/{id:[^/]*}
- Same as ‘/user/{id}’ from the previous example./user/{id:[0-9a-fA-F]{1,8}}
- Similar to the previous example, but only matches if the id parameter consists of 1 to 8 hex digits./files/{path:.*}
- Matches any URL starting with ‘/files/’ and captures the rest of the path into the parameter ‘path’./files/*path
- Ditto. Special syntax for catch all.
目前,尚未实践过,猜测是对URL进行捕获,如果不符合该正则表达式,则该参数不存在
多于1个参数
使用URL参数写法:url: "/contacts?myParam1&myParam2"
Using Parameters without Specifying Them in State URLs
.state('contacts', { url: "/contacts", params: { param1: null }, templateUrl: 'contacts.html'})
Router State Transition Events
stateChangeSuccess - fired once the state transition is complete
$stateChangeError - fires when an error occurs during transition
event.preventDefault() - to prevent the transition from occurring
State Inheritance
状态也可以继承,继承的唯一目的就是使用嵌套的ui-view。
.state('view1', { resolve: { myData: 'someVal'; } …}).state('view1.child', { url: '/detail/{param1}', templateUrl: 'view1Detail.html', controller: "ChildCtrl as child" …});ChildCtrl.$inject = ['myData'];function ChildCtrl (myData) { … }
状态继承的时候,resolve成员也可以继承,如上。