如何使用 TypeScript 编写 AngularJS 的 Controller

 我来答
就烦条0o
2017-02-08 · 知道合伙人软件行家
就烦条0o
知道合伙人软件行家
采纳数:33315 获赞数:46492
从事多年系统运维,喜欢编写各种小程序和脚本。

向TA提问 私信TA
展开全部
AngularJS 有许多强大的特性,其中之一便是 Controller。在这篇文章里,我将介绍如何使用 TypeScript 去编写 AngularJS 的 Controller。

Controller 通常用来增强 AngularJS 作用域(Scope)
。当一个 Controller 通过 ng-controller
指令连接到 DOM 上的时候,Angular 将使用指定的 Conroller 函数初始化一个新的 Controller 对象。一个新的子 scope 将被创建并作为 $scope
变量注入到 Controller 的构造函数当中。

有两个选项将 Controller 连接到视图当中,一种是 Controller 作为语法,另外一种是使用 $scope
。如果使用 Controller 语法,Controller 实例将被分配一个在新作用域上的属性。

要想知道类型定义,看看 这个令人吃惊的仓库
,它收集了几乎所有流行的 JavaScript 库。这些类型定义可以让我们得到任何编译时错误和 IDE
的智能支持。我使用 Visual Studio 和 Visual Code,它们都对 TypeScript 有很好的支持。

正如上面提到的,AngularJS 只要在被请求的时候都将创建一个Controller 实例。所以,一个 Controller 可以使用
TypeScript 里的类去定义,就像我们所知道的,一个类是可以被实例化的。让我们来使用在视图里 Controller
作为语法的方法来定义一个 Dashboard Controller。下面的代码没有使用 $scope
服务。
interface IDashboardVm {
news: { title: string, description: string };
messageCount: number;
people: Array<any>;
title: string;
getMessageCount: () => ng.IPromise<number>;
getPeople: () => ng.IPromise<Array<any>>;
}

class DashboardController implements IDashboardVm {
static $inject: Array<string> = ['dataservice'];
constructor(private dataservice: app.core.IDataService) {
this.getMessageCount();
this.getPeople();
}

news = {
title: 'News',
description: 'Internal server team is excited about AngularJS, TypeScript & JavaScript'
};
messageCount: number = 0;
people: Array<any> = [];
hubsSummary: Array<any> = [];
title: string = 'Dashboard';

getMessageCount() {
return this.dataservice.getMessageCount().then((data) => {
this.messageCount = data;
return this.messageCount;
});
}

getPeople() {
return this.dataservice.getPeople().then((data) => {
this.people = data;
return this.people;
});
}
}

angular.module('app.dashboard').controller('DashboardController', DashboardController);

利用 TypeScript 的强类型特征,最好创建一个包含所有和视图相关成员和行为的接口。这就可以使为一个 Controller 定义实现变得容易,而且这个接口如果需要就可以做成一个抽象方法在其他地方使用了。所以,上面代码里我创建了一个名为 IDashboardVm
的接口。

接着,名为 DashboardController
的 Controller 实现了这个接口并给每个成员定义了默认状态。看这个类的静态变量 $inject
,它告诉了 AngularJS DI
在初始化这个 Controller 之前注入哪些依赖。然后构造器在需要的依赖的相同顺序定义了参数当它们被注入到那些参数的时候。

类所提到的依赖都是相当直接了当的,假设 dataservice
是一个自定义的 AngularJS 服务,它封装了所有对服务器发起的 HTTP 请求。根据接口里的每个定义,接下来我们要为这些行为定义实现,内部调用 dataservice
方法。它使用了 promises
去返回待会儿要分配到 Controller 成员上去控制状态的响应。

真正重要的是要注意使用 Angular 的模块 API 注册这个 Controller
的位置。上面的代码里,首先定义了类然后完成其注册。如果这个顺序交换的话,Angular 就将找不到我们这个 Controller
的实现了。当使用一个 JavaScript 构造函数就可以很好地解决问题,因为 函数提升起到了很重要的作用


下面是这个 Controller 如何在 Angular-UI UI-Router
中使用的代码片段,但如果你想使用 Angular 内置路由模块的话概念是一样的。注意,这只展示了使用 controllerAs
语法进行配置的部分。
config: {
url: '/',
templateUrl: 'app/dashboard/dashboard.html',
controller: 'DashboardController',
controllerAs: 'vm',
title: 'dashboard',
}

如果你想使用 $scope
服务的话,那么就可以像下面的代码片段那样扩展上面的接口。这将确保所有 IScope 有的成员可以通过接口访问到。使用这个方法还需要改变一下 Controller 类的实现,因为现在它需要 $scope
服务的依赖了。自定义接口类型接着就可以在构造器使用 $scope
参数获得强类型和智能支持了。
interface IDashboardVm extends angular.IScope {
news: { title: string, description: string };
messageCount: number;
people: Array<any>;
title: string;
getMessageCount: () => ng.IPromise<number>;
getPeople: () => ng.IPromise<Array<any>>;
}
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式