如何在具有角度注入参数的打字稿中创建新对象

时间:2016-03-31 12:53:46

标签: angularjs dependency-injection typescript inject

我有一个打字稿类,其中构造函数我有一个普通和一个角度注入的参数:

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?它也不会起作用,因为它不会识别范围而且不会被定义。

那么,我怎样才能让它发挥作用?

我的方法

让我们说我在另一个班级,我想在其中创建一个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);
    }
}

我宁愿调用类似var clazz = new MyClass('myName');的内容,并在MyClass中自动注入$filter作为依赖项。这有可能吗?

2 个答案:

答案 0 :(得分:4)

我认为你缺少关于DI(注射)的一些东西。关键是不要手动创建任何依赖项。相反,总是解决它们并使用Angular,这是在构造函数中自动完成的。唯一的例外应该是具有0个角度依赖性的类,并且限制为不像纯实体/数据类那样的行为。

此外,Typescript为您提供定义接口(合同)的能力。您应该创建它们并将它们用作参考点而不是直接使用类类型。这将允许您更改行为甚至定义(提供松耦合)。这也使单元测试更容易。

您的示例可以像这样重写:

Sub Report()
    Dim k As Long

    With ThisWorkbook.Worksheets("Testing")
        If .AutoFilterMode Then .AutoFilterMode = False
        With .Range(.Cells(21, "F"), .Cells(Rows.Count, "F").End(xlUp))
            .AutoFilter Field:=1, Criteria1:="Fatal"
            k = Application.Subtotal(103, .Cells) - 1 'minus 1 for the header
            Debug.Print k
        End With
        If .AutoFilterMode Then .AutoFilterMode = False
    End With

End Sub

现在使用名为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(); } } 的angular注册MyClass,并使用angular注册ClassUsingTheOtherClass。注册它们取决于它们的使用(控制器,服务,工厂,过滤器等)。

当angular创建ngMyService的实例时,它会自动将ClassUsingTheOtherClass注入构造函数中。 MyClass反过来会自动将MyClass注入构造函数中。

最后,我认为$filter中的字符串name参数没有用处,所以我删除了它。你永远无法注入这个,因为你不能注册一个带有angular的字符串来注入。您可以在类型本身中对名称进行硬编码,也可以提供可由MyClass的用户设置的name属性/字段(将字段添加到接口MyClass),但这样在我看来打破了高凝聚力的规则。

答案 1 :(得分:-2)

githubService.getAccount()

通过修改类,使export class MyClass { public static $inject = ['$scope']; constructor(name:string, $scope?: ng.IScope) { //do things... } } 后面有一个问号,告诉编译器$scope是一个可选参数。

现在您只需运行$scope