如何在具有 angular 注入参数的打字稿中创建新对象
How to create new object in typescript having angular-injected parameters
我有一个打字稿class,其中构造函数我有一个普通参数和一个angular-注入参数:
export class MyClass {
private translation:string;
public static $inject = ['$filter'];
constructor(name:string, $filter: ng.IFilterService) {
this.translation = filter('translate')('code').toString();
}
}
如果我现在想创建一个对象,我该怎么做?
new MyClass('myname'); //won't compile because there are too few parameters
new MyClass('myname', filter); //makes no sense since I want to inject it
即使我写 $filter?
它也不会工作,因为它无法识别范围并且它将是未定义的。
那么,我怎样才能让它工作?
我的方法
假设我在另一个 class 中,我想在其中创建一个 MyClass 对象。下面的代码可以工作,但我不喜欢在这个 class 中也必须注入 $filter 的想法,因为它不需要它。
export class ClassUsingTheOtherClass {
private filter:ng.IFilterService;
public static $inject = ['$filter'];
constructor($filter: ng.IFilterService) {
this.filter = $filter;
}
doThings() {
var clazz = new MyClass('myName', this.filter);
}
}
我宁愿这样调用 var clazz = new MyClass('myName');
并让 $filter
作为依赖项自动注入到 MyClass 中。这可能吗?
export class MyClass {
public static $inject = ['$scope'];
constructor(name:string, $scope?: ng.IScope) {
//do things...
}
}
通过修改 class,使 $scope
后面有一个问号,您告诉编译器 $scope
是一个可选参数。
现在您可以 运行 new MyClass('myname');
.
我认为您遗漏了一些有关 DI(注入)的信息。关键是不要手动创建任何依赖项。相反,总是解决它们并使用 Angular 这是在构造函数中自动完成的。唯一的例外应该是 class 具有 0 angular 依赖关系并且没有像纯 entity/data class.
这样的行为的限制
Typescript 还为您提供了定义接口(契约)的能力。您应该创建它们并将它们用作参考点,而不是直接使用 class 类型。这将允许您更改行为甚至定义(提供松耦合)。这也使单元测试更容易。
您的示例可以这样重写:
export interface IMyService{
doThing:()=>void;
}
// should be registered with angular with service name 'ngMyService'
export class MyClass implements IMyService {
private translation:string;
public static $inject = ['$filter'];
constructor($filter: ng.IFilterService) {
this.translation = $filter('translate')('code').toString();
}
doThing() : void {
// something
}
}
export class ClassUsingTheOtherClass {
public static $inject = ['ngMyService'];
constructor(private myService: IMyService) {
}
doThings() {
this.myService.doThing();
}
}
现在用名称 ngMyService
向 angular 注册 MyClass
并向 angular 注册 ClassUsingTheOtherClass。您在哪里注册它们取决于它们的用途(控制器、服务、工厂、过滤器等)。
当 angular 创建 ClassUsingTheOtherClass
的实例时,它会自动将 MyClass
注入到构造函数中。 MyClass
反过来会自动将 $filter
注入到构造函数中。
最后我发现 MyClass
中的字符串 name
参数没有用,所以我删除了它。你将永远无法注入这个,因为你不能注册一个带有 angular 的字符串来注入。您可以在类型本身中对名称进行硬编码,也可以提供一个 name
属性 / 可以由 MyClass
的用户设置的字段(将字段添加到接口 IMyService
) 但在我看来这打破了高内聚规则。
我有一个打字稿class,其中构造函数我有一个普通参数和一个angular-注入参数:
export class MyClass {
private translation:string;
public static $inject = ['$filter'];
constructor(name:string, $filter: ng.IFilterService) {
this.translation = filter('translate')('code').toString();
}
}
如果我现在想创建一个对象,我该怎么做?
new MyClass('myname'); //won't compile because there are too few parameters
new MyClass('myname', filter); //makes no sense since I want to inject it
即使我写 $filter?
它也不会工作,因为它无法识别范围并且它将是未定义的。
那么,我怎样才能让它工作?
我的方法
假设我在另一个 class 中,我想在其中创建一个 MyClass 对象。下面的代码可以工作,但我不喜欢在这个 class 中也必须注入 $filter 的想法,因为它不需要它。
export class ClassUsingTheOtherClass {
private filter:ng.IFilterService;
public static $inject = ['$filter'];
constructor($filter: ng.IFilterService) {
this.filter = $filter;
}
doThings() {
var clazz = new MyClass('myName', this.filter);
}
}
我宁愿这样调用 var clazz = new MyClass('myName');
并让 $filter
作为依赖项自动注入到 MyClass 中。这可能吗?
export class MyClass {
public static $inject = ['$scope'];
constructor(name:string, $scope?: ng.IScope) {
//do things...
}
}
通过修改 class,使 $scope
后面有一个问号,您告诉编译器 $scope
是一个可选参数。
现在您可以 运行 new MyClass('myname');
.
我认为您遗漏了一些有关 DI(注入)的信息。关键是不要手动创建任何依赖项。相反,总是解决它们并使用 Angular 这是在构造函数中自动完成的。唯一的例外应该是 class 具有 0 angular 依赖关系并且没有像纯 entity/data class.
这样的行为的限制Typescript 还为您提供了定义接口(契约)的能力。您应该创建它们并将它们用作参考点,而不是直接使用 class 类型。这将允许您更改行为甚至定义(提供松耦合)。这也使单元测试更容易。
您的示例可以这样重写:
export interface IMyService{
doThing:()=>void;
}
// should be registered with angular with service name 'ngMyService'
export class MyClass implements IMyService {
private translation:string;
public static $inject = ['$filter'];
constructor($filter: ng.IFilterService) {
this.translation = $filter('translate')('code').toString();
}
doThing() : void {
// something
}
}
export class ClassUsingTheOtherClass {
public static $inject = ['ngMyService'];
constructor(private myService: IMyService) {
}
doThings() {
this.myService.doThing();
}
}
现在用名称 ngMyService
向 angular 注册 MyClass
并向 angular 注册 ClassUsingTheOtherClass。您在哪里注册它们取决于它们的用途(控制器、服务、工厂、过滤器等)。
当 angular 创建 ClassUsingTheOtherClass
的实例时,它会自动将 MyClass
注入到构造函数中。 MyClass
反过来会自动将 $filter
注入到构造函数中。
最后我发现 MyClass
中的字符串 name
参数没有用,所以我删除了它。你将永远无法注入这个,因为你不能注册一个带有 angular 的字符串来注入。您可以在类型本身中对名称进行硬编码,也可以提供一个 name
属性 / 可以由 MyClass
的用户设置的字段(将字段添加到接口 IMyService
) 但在我看来这打破了高内聚规则。