建立我的第一个应用
通过。
建立模块
模块是应用的组成部分。
新建一个文件,命名为 app.urgent.js
。urgent 是 SHB 的一个特殊符号,代表最早加载的 js 文件。在 app.urgent.js
中,编写以下代码:
// Source: app/app.urgent.js
// 建立 app 模块
angular.module('app', []);
编辑文件 project.json
,在 main
字段中指定入口模块 app
。
{
"name": "Static HTML App",
"main": "app",
"dependencies": {
"angular-route": "~1.2"
},
"proxies": {
"/api": "http://localhost:8080"
}
}
这样就建立了一个名为 app
的模块。接下来的教程均会以该模块为例进行说明。在实际环境中,开发者需要自行决定模块的名称与依赖。
建立路由
使用路由来建立 url 与页面的对应关系。
修改 app.urgent.js
,加入路由模块与相应的配置:
// Source: app/app.urgent.js
// 加入对路由模块的依赖
angular.module('app', ['ngRoute']).config(config);
// 配置路由,使用注解语法标明注入的组件
// @ngInject
function config($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'root.html'
});
}
这样就建立了一个路由关系:当用户访问网站的根目录时,系统会加载 root.html
作为页面的展示部分。
建立页面
单页面应用使用 HTML 片段进行开发。编写代码时无需编写 head 或引入额外的 script。下面是 root.html
的例子:
<!-- Source: root.html -->
<h1>你好世界</h1>
<p>这是我的第一个应用</p>
建立控制器
控制器用于实现用户交互逻辑。
// Source: app/root-controller.js
// 定义 Controller
angular.module('app').controller('RootController', RootController);
// 实现 Controller
function RootController() {
var vm = this;
vm.text = '你好世界';
}
将控制器加入路由,允许页面使用定义好的控制器。
// Source: app/app.js
angular.module('app', ['ngRoute']).config(config);
// @ngInject
function config($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'root.html',
controller: 'RootController',
controllerAs: 'root'
});
}
在页面使用控制器控制的变量
<!-- Source: app/root.html -->
<h1 ng-bind="root.text"></h1>
<p>这是我的第一个应用</p>
使用服务抽象业务逻辑
服务用于编写与页面无关的逻辑,比如 http 请求。
// Source: app/test-service.js
angular.module('app').service('TestService', TestService);
// @ngInject
function TestService($http, $q) {
/**
* TestService.getDate
* 测试 HTTP 调用
* @return promise
*/
this.getData = function () {
var deferred = $q.defer();
$http.get('http://localhost:9001/test')
.success(deferred.resolve)
.error(deferred.reject);
return deferred.promise;
}
}
使用 Promise 获取异步操作结果
$q
用于处理异步操作。
// Source: app/root-controller.js
// 定义 Controller
angular.module('app').controller('RootController', RootController);
// 实现 Controller
// @ngInject
function RootController(TestService) {
var vm = this;
// 调用 Service 方法,并处理 promise 得到的结果
TestService.getData().then(function () {
vm.text = '你好世界';
});
}
限制路由访问
使用 resolve 配置路由是否成功,如果返回一个失败的 promise,则路由失败。
// Source: app/app.js
angular.module('app', ['ngRoute']).config(config);
// @ngInject
function config($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'root.html',
controller: 'RootController',
resolve: {
acl: acl
}
});
}
// @ngInject
function acl($q) {
var deferred = $q.defer();
deferred.reject();
return deferred.promise;
}
使用 Directive 封装 View 组件
directive 通常有两个作用:
- 将一系列的 html 与行为封装成一个标签;
- 适配其他框架的初始化代码;
定义 directive
// Source: app/list.js
angular.module('app').directive('list', list);
// @ngInject
function list($http) {
return {
template: [
'<ul>',
'<li ng-repeat="item in items">{{item.text}}</li>',
'</ul>'
].join(''),
link: link
};
function link(scope, element, attrs) {
// 获取 data-source 属性的值,并请求后台
$http.get(attrs.source).success(function (result) {
scope.items = result;
});
}
}
使用 directive
<h1>这是 directive 例子</h1>
<list data-source="/raw/list.json"></list>
上面例子的数据
[
{"text": "foo"},
{"text": "bar"},
{"text": "baz"}
]