ibe*_*beu 4 dependency-injection inject angularjs typescript
我有一个打字稿类,其中构造函数有一个普通参数和一个角度注入参数:
export class MyClass {
private translation:string;
public static $inject = ['$filter'];
constructor(name:string, $filter: ng.IFilterService) {
this.translation = filter('translate')('code').toString();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我现在想创建一个对象,我该怎么做呢?
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
Run Code Online (Sandbox Code Playgroud)
即使我写了$filter?它也不会工作,因为它无法识别范围并且它将是未定义的。
那么,我怎样才能让它发挥作用呢?
我的方法
假设我在另一个类中,我想在其中创建 MyClass 的对象。以下代码可以工作,但我不喜欢在此类中也注入 $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);
}
}
Run Code Online (Sandbox Code Playgroud)
我宁愿调用类似的东西var clazz = new MyClass('myName');并$filter自动注入 MyClass 中的依赖项。这有可能吗?
我认为你错过了一些关于 DI(注入)的事情。重点是不要手动创建任何依赖项。相反,始终解决它们,而对于 Angular,这是在构造函数中自动完成的。唯一的例外应该是具有 0 角度依赖关系的类,并且仅限于没有像纯实体/数据类那样的行为。
Typescript 还使您能够定义接口(契约)。您应该创建它们并使用它们作为参考点,而不是直接使用您的类类型。这将允许您更改行为甚至定义(提供松散耦合)。这也使得单元测试变得更加容易。
您的示例可以像这样重写:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
现在使用MyClass名称注册 Angular ngMyService,并使用 Angular 注册 ClassUsingTheOtherClass。注册它们的位置取决于它们的用途(控制器、服务、工厂、过滤器等)。
当 Angular 创建实例时,ClassUsingTheOtherClass它会自动MyClass注入到构造函数中。MyClass反过来会自动$filter注入到构造函数中。
最后我发现字符串name参数没有任何用途MyClass,所以我将其删除。您将永远无法注入它,因为您无法注册带有要注入的角度的字符串。您可以在类型本身中对名称进行硬编码,或者提供name可由用户设置的属性/字段MyClass(将字段添加到接口中IMyService),但这在我看来打破了高内聚规则。
| 归档时间: |
|
| 查看次数: |
6179 次 |
| 最近记录: |