E.g。在angularJS中,我可以使用以下结构:
myApp.factory('MyFactory', function(injectable) {
return function(param) {
this.saySomething = function() {
alert("Param=" + param + " injectable=" +injectable);
}
};
});
以后可以这样使用:
function(MyFactory) {
new MyFactory().saySomething();
}
当调用传递给方法factory
的函数时,参数injectable
被关在笼子中,并且可以进一步用于MyFactory
的新实例,而无需再次指定该参数。
现在我想使用TypeScript,显然我想指定我的MyFactory
是新的,并且有一个函数saySomething
。我怎么能优雅地做到这一点?
我可以这样写:
class MyFactory {
constructor(private injectable, private param) {}
saySomething() {
alert(...);
}
}
myApp.factory('myFactory', function(injectable) {
return function(param) {
return new MyFactory(injectable, param);
}
});
但这改变了API:
function(myFactory) {
myFactory().saySomething();
}
我想知道它是否会更优雅,因为我喜欢" new"很清楚地表明创建了一个新的唯一对象,这个对象创建是工厂的整个目的。
答案 0 :(得分:1)
**编辑:TypeScript> = 1.6支持class expressions,您现在可以编写如下内容:
myApp.factory(injectable: SomeService) {
class TodoItem {
...
}
}
**原始答案:
我遇到了同样的问题:使用AngularJS和ES5,我喜欢依赖注入而不是污染构造函数,并且能够使用new
关键字。
使用ES6,您可以将一个类包装在一个函数中,TypeScript尚不支持它(参见https://github.com/Microsoft/TypeScript/issues/307)。
我在这里做的事情(MyFactory现在是来自todo app的TodoItem类更具相关性):
class TodoItem {
title: string;
completed: boolean;
date: Date;
constructor(private injectable: SomeService) { }
doSomething() {
alert(this.injectable);
}
}
class TodoItemFactory() {
constructor(private injectable: SomeService) { }
create(): TodoItem {
return new TodoItem(this.injectable);
}
// JSON from the server
createFromJson(data: any): TodoItem {
var todoItem = new TodoItem(this.injectable);
todoItem.title = data.title;
todoItem.completed = data.completed;
todoItem.date = data.date;
return todoItem;
}
}
// In ES5: myApp.factory('TodoItem', function(injectable) { ... });
myApp.service('TodoItemFactory', TodoItemFactory);
class TodosCtrl {
// In ES5: myApp.controller('TodosCtrl', function(TodoItem) { ... });
constructor(private todoItemFactory: TodoItemFactory) { }
doSomething() {
// In ES5: var todoItem1 = new TodoItem();
var todoItem1 = this.todoItemFactory.create();
// In ES5: var todoItem2 = TodoItem.createFromJson(...)
var todoItem2 = this.todoItemFactory.createFromJson(
{title: "Meet with Alex", completed: false}
);
}
}
这不如ES5和函数优雅(并且不使用TypeScript的类是不行): - /
我想写的是:
@Factory
@InjectServices(injectable: SomeService, ...)
class TodoItem {
title: string;
completed: boolean;
date: Date;
// No DI pollution
constructor() { }
saySomething() {
alert(this.injectable);
}
static createFromJson(data: string): TodoItem {
...
}
}
@Controller
@InjectFactories(TodoItem: TodoItem, ...)
class TodosCtrl {
constructor() { }
doSomething() {
var todoItem1 = new TodoItem();
var todoItem2 = TodoItem.createFromJson({title: "Meet with Alex"});
}
}
或使用功能:
myApp.factory(injectable: SomeService) {
class TodoItem {
title: string;
completed: boolean;
date: Date;
// No constructor pollution
constructor() { }
saySomething() {
alert(injectable);
}
static createFromJson(data: string): TodoItem {
...
}
}
}
myApp.controller(TodoItem: TodoItem) {
class TodosCtrl {
constructor() { }
doSomething() {
var todoItem1 = new TodoItem();
var todoItem2 = TodoItem.createFromJson({title: "Meet with Alex"});
}
}
}
答案 1 :(得分:0)
我可以写这样的东西
这就是我的工作
我可以在函数
中创建TypeScript类吗?
不需要位于文件的顶层或模块中。仅供参考,如果能够在函数内创建它,信息将被锁定在该函数内,并且至少类型信息将是无用的。
答案 2 :(得分:0)
实例化MyFactory的多个实例的原因是什么?您是否希望将工厂的单个实例注入到相关代码中?
我认为使用你提供的类声明实际上会在注入后显示:
function(myFactory) {
myFactory.saySomething();
}
如果你真的需要将构造函数传递给你的依赖代码,那么我认为你将不得不抛弃TypeScript类,因为它们不能在函数内部定义,这意味着你无法创建一个关注注入此函数的变量。
您始终可以选择仅使用TypeScript中的函数而不是类。仍然可以获得强大的输入效果,并可以在其上调用“新”,因为它在一天结束时仍然是.js功能。这是一个稍微更多的TypeScriptiffied版本:
myApp.factory('MyFactory', (injectable: ng.SomeService) => {
return (param: string) => {
return {
saySomething: () {
alert("Param=" + param + " injectable=" +injectable);
}
};
};
});