我使用AngularJS和TypeScript。我想实现一个AngularJS服务使用Typescript类,像这样:
class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
angular.module('app.services.helloService',[]).factory('helloService',() => {
return new HelloService();
});
这将编译为以下JavaScript代码:
var HelloService = (function () {
function HelloService() {
}
HelloService.prototype.getWelcomeMessage = function () {
return "Hello";
};
return HelloService;
})();
angular.module('app.services.helloService',function () {
return new HelloService();
});
这会使用变量HelloService污染全局命名空间,我显然不想要。 (使用Chrome的控制台我验证了HelloService是一个对象。)我如何解决/避免这个问题?
我试过明显:
angular.module('app.services.helloService',function () {
class HelloService { ...}
return new HelloService();
});
但是这给我一个编译错误(“意外的令牌;’语句’期望。
一个可能的解决方案,我可以想到的是使用TypeScript的导入和导出某种方式,这反过来将使用RequireJS。这可能将HelloService包装在define函数中,从而避免使用HelloService污染全局范围。但是,我现在不想在我的AngularJS应用程序中使用RequireJS,因为我认为AngularJS足够好我的使用,它增加了复杂性。
所以,我的问题是,如何使用不污染全局范围的TypeScript类定义AngularJS服务?
2016-05-06:使用ES6样式模块的新示例
static $ inject数组和构造函数与上一个示例保持不变。
唯一的变化是将类拆分为多个文件,并使用ES6模块拉入类定义。
/lib/HelloService.ts:
export class HelloService {
public getWelcomeMessage():String {
return "Hello from HelloService";
}
}
/lib/AnotherService.ts:
import {HelloService} from './HelloService';
/**
* Service that depends on HelloService.
*/
export class AnotherService {
// Define `HelloService` as a dependency.
static $inject = ['HelloService'];
constructor(
// Add the parameter and type deFinition.
public HelloService: HelloService
){}
public getWelcomeMessage():String {
// Access the service as: `this.HelloService`
// Enjoy auto-completion and type safety :)
var helloMsg = this.HelloService.getWelcomeMessage();
return "Welcome from AnotherService," + helloMsg;
}
}
/index.ts:
// Using the services.
import {HelloService} from './lib/HelloService';
import {AnotherService} from './lib/AnotherService';
angular.module('HelloApp',[])
.service('HelloService',HelloService)
.service('AnotherService',AnotherService)
.run(['AnotherService',function(AnotherService: AnotherService){
console.log(AnotherService.getWelcomeMessage());
}]);
上一个答案:使用命名空间
建筑从Steve Fenton’s answer:
要允许依赖注入,在类上添加一个静态$ inject数组。
有关$ inject数组如何工作,请参见Angular $injector documentation。
依赖关系将按照数组给出的顺序注入到你的构造函数中(并使它与缩小一起使用)。
依赖注入示例:
namespace MyModule {
/**
* Angular Service
*/
export class HelloService {
public getWelcomeMessage():String {
return "Hello from HelloService";
}
}
/**
* Service that depends on HelloService.
*/
export class AnotherService {
// Define `HelloService` as a dependency.
static $inject = ['HelloService'];
constructor(
// Add the parameter and type deFinition.
public HelloService: MyModule.HelloService
){}
public getWelcomeMessage():String {
// Access the service as: `this.HelloService`
// Enjoy auto-completion and type safety :)
var helloMsg = this.HelloService.getWelcomeMessage();
return "Welcome from AnotherService," + helloMsg;
}
}
}
// Using the services.
angular.module('app.services.helloService',MyModule.HelloService)
.service('AnotherService',MyModule.AnotherService)
.run(['AnotherService',function(AnotherService: MyModule.AnotherService){
console.log(AnotherService.getWelcomeMessage());
}]);