什么是ui-router
- ui-router是AngularUI库最有用的组件之一(AngularUI库由AngularJS社区构建)。它是一个第三方路由框架,允许通过状态机制组织接口,而不是简单的URL路由。
作用
- 和ngRoute功能一样,可以定义在任意状态内的模板都处在中
- 与ngRoute不同的是,每个模板中可以包含自己的中,也就是我们说的嵌套路由.
如何使用
首先,需要定义路由,可以使用.config方法,和ngRoute不同的是,路由是要设置在 routeProvider上,而是将状态设置在 r o u t e P r o v i d e r 上 , 而 是 将 状 态 设 置 在 stateProvider上,
$stateProvider.state(stateName, stateConfig)
stateName::字符串
stateConfig:object对象,可以设置url、template、controller等属性.
了解完定义状态的用法,我们可以看一下实例代码:
app.config(function($stateProvider) {
$stateProvider
.state('C1', {
url:'/C1',
template: '进入C1状态
'
})
.state('C2', {
url: '/C2',
templateUrl: 'Htmls/C2.html'
})
.state('C3', {
url: '/C3',
templateProvider: function() {
return '进入C3状态
';
}
})
});
上面代码中,我们给状态配置对象分配了三个状态,“C1”、“C2”和”C3”。当应用程序状态为以上三个状态时,url会自动切换到定义的地址,而且也会显示相应的html模板。其中,有三种显示html模板的方式
template: 一个html内容字符串或一个能返回html字符串的函数, 如状态C1处代码;
templateUrl: 一个html模板的路径字符串或者是一个能返回URL路径字符串的函数,如状态C2处代码;
templateProvider:一个能返回URL路径字符串的函数,如状态C3处代码;
现在,我们来写一下index.html和app.js文件,实现一下ui-router:
<html>
<head>
<meta charset="utf-8" />
<title>indextitle>
<link href="css/index.css" rel="stylesheet" />
<script src="js/lib/angular/angular.min.js">script>
<script src="js/lib/angular-ui-router/release/angular-ui-router.min.js">script>
<script src="app.js">script>
head>
<body ng-app="TrialApp" ng-controller="mainController" style="background-color: lightblue;">
<h1>index页面h1>
<div style="width: 80%; float: right;background-color: #C0C0C0;">
<h1>路由区域h1>
<ui-view> ui-view>
div>
body>
html>
'use strict';
// Define `TrialApp` module
var app = angular.module('TrialApp', ['ui.router']);
// Define routers
app.config(function($stateProvider) {
$stateProvider
.state('C1', {
url:'/C1',
template: '进入C1状态
'
})
.state('C2', {
url: '/C2',
templateUrl: 'Htmls/C2.html'
})
.state('C3', {
url: '/C3',
templateProvider: function() {
return '进入C3状态
';
}
})
});
app.run(function($state) {
$state.go('C1');
});
上述代码是在加载该模块的时候调用$state.go(‘C1’);,以激活C1状态。运行以后就是以下效果:
方法2:在html文档中区域之外的地方,添加stateName链接,代码如下:
<a ui-sref='C1'>C1a><br />
<a ui-sref='C2'>C2a><br />
<a ui-sref='C3'>C3a>
由于上述效果有点丑,我们调整下html代码:
<html>
<head>
<meta charset="utf-8" />
<title>indextitle>
<link href="css/index.css" rel="stylesheet" />
<script src="js/lib/angular/angular.min.js">script>
<script src="js/lib/angular-ui-router/release/angular-ui-router.min.js">script>
<script src="app.js">script>
head>
<body ng-app="TrialApp" ng-controller="mainController" style="background-color: lavender;">
<h1>index页面h1>
<div style="width: 20%; float: left;background-color: lightgoldenrodyellow;text-align: center;">
<a ui-sref='C1'>C1a><br />
<a ui-sref='C2'>C2a><br />
<a ui-sref='C3'>C3a>
div>
<div style="width: 80%; float: right;background-color: #C0C0C0;">
<h1>路由区域h1>
<ui-view> ui-view>
div>
body>
html>
'use strict';
// Define `TrialApp` module
var app = angular.module('TrialApp', ['ui.router']);
// Define routers
app.config(function($stateProvider) {
$stateProvider
.state('C1', {
url:'/C1',
template: '进入C1状态
',
controller:'C1Controller'
})
.state('C2', {
url: '/C2',
templateUrl: 'Htmls/C2.html',
controller: function() {
this.test = 'world!';
},
controllerAs: 'C2Ctrl'
})
.state('C3', {
url: '/C3',
templateProvider: function() {
return '进入C3状态
'
+ '{{t}}
';
},
controller: function($scope) {
$scope.t = 'C3Controller is on!';
}
})
});
app.controller('mainController', function() {
return alert('hello!');
});
app.run(function($state) {
$state.go('C1');
});
另外创建一个js文件“C1Controller”,代码如下:
'use strict';
//Define `C1Controller`
app.controller('C1Controller', function() {
alert('C1Controller is on!');
});
C2.html代码修改如下:
<h4>进入状态C2h4><br />
<p>Hello, {{C2Ctrl.test}}p>
上面的代码使用了上述两种方法加载了controller。
名字所对应的文件会报错Error: [$controller:ctrlreg],这是都因为controller文件没有被注册成功,所以在
编写完之后要注意检查这一点。
还有一点值得注意的是,在状态C2和C3中,分别都用了内置controller的方法,在方法中创建变量,并在对应页面中显示其值。
在C2中,用了this.test(this指当前对象)声明并初始化变量,为了能在C2对应页面中显示变量值,需要将controller设置别别名,controllerAs: ‘C2Ctrl’, 然后在对应html模板中用{{C2Ctrl.test}}
而在C3中,在controller中用 scope创建变量,在对应html模板中用t,这里 s c o p e 创 建 变 量 , 在 对 应 h t m l 模 板 中 用 t , 这 里 scope对应的就是该controller的作用域,所以在与其关联的html文本中,直接写出该变量即可。
那这里,有人也许会问,我在这里也写一个contorllerAs,给controller取个别名,然后再{{controller.变量}}行不行? 答案是不行(亲测有效)。记得AngularJS官网的phonecatApp示例中,曾提到过一句话,如果应用规模大,controller数量多而杂的情况下,在设置controller过程中,尽量避免 scope。个人觉得是因为, s c o p e 。 个 人 觉 得 是 因 为 , scope代表一个controller的作用域,如果有多个controller,那就会有多个 scope,那如果大家都有 s c o p e , 那 如 果 大 家 都 有 scope,那放在一起,谁会清楚这是那个作用域的属性?所以个人
觉得controller给controller起个别名是一个比较好的方法,这样一眼就是识别这是哪个controller,方便代码后期维护,也方便别人(你的同事们)解读。
好了,今天主要是对ui-router入门的讲解。希望能通过这一简单的示例,让大家能对ui-router的一个基本原理有所了解。下一次将会进阶地讲ui-router的东西,比如多个视图、路由嵌套及与ngRoute的对比。如果本文有哪些讲解得不够细致或有错误的地方,欢迎读者指正。