如何使用带有角度依赖注入的打字稿继承

Posted

技术标签:

【中文标题】如何使用带有角度依赖注入的打字稿继承【英文标题】:How to use typescript inheritance with angular dependency injection 【发布时间】:2016-01-06 14:22:03 【问题描述】:

我正在使用 Angular 构建一个应用程序,并且最近切换到了 TypeScript。我的应用程序的核心由多个相互交互的实际类组成(因此不仅仅是全局服务)。我这样做的方法如下:

class Person 
    constructor(private $http, public name: string) 
        // ... use this.$http for some task
    


class PersonFactory 
    static $inject = ['$http'];

    constructor(private $http) 

    create(name: string) 
        return new Person(this.$http, name);
    


angular.module('app').service('personFactory', PersonFactory);

因此,如果其他类需要创建Person 对象,则需要注入PersonFactory 并调用其create 方法。这工作正常,即使它需要一些样板。

当我想对 Person 进行子类化时,我的主要问题出现了:

class Student extends Person 
    constructor(private $http) 
        super(this.$http, 'Some actual name')
    

我可以遵循与上面相同的模式,但是我需要再次创建一个StudentFactory,它将所需的服务(如 $http)传递给类构造函数,然后将其传递给超级方法的构造函数.如果我现在有多个这样的扩展类并且要更改基类Person,我必须更改每个扩展类及其工厂。有没有更好的方法来解决这个问题?在我的核心应用程序中删除对 Angular 服务的所有依赖项并仅将 Angular 用于 UI 代码会更好吗?

解决方案

按照答案中的建议,我将 $injector 服务添加到窗口中,如下所示:

module('app').run(['$injector', function($injector) 
    window.$injector = $injector;
]);

现在可以在任何类中使用该服务来获取其他服务,例如 $http。 但这对单元测试不起作用,所以我不得不再次将注入器放在全局范围内:

// MyClass.test.js
var $injector;

describe('My class', function() 
    beforeEach(module('app'));

    beforeEach(inject(function(_$injector_) 
        $injector = _$injector_;
    ));

    ...
);

【问题讨论】:

【参考方案1】:

我不得不更改每个扩展类及其工厂。有没有更好的方法来解决这个问题

只需注入$injector,然后基类就可以使用$injector.get() 得到它想要的东西。

甚至更疯狂...将$injector(它是一个单例)放在全局范围/或某个模块上...然后在您的类中使用它来获取特定于角度的东西。

【讨论】:

因此您将摆脱所有注入注释及其相应的构造函数参数,并且每次需要时只需使用$injector.get(),例如$http?例如,一些类方法:makeApiCall() $injector.get('$http').get(...).then(...); $injector 将是一个类成员或您在全局范围内建议的那样。 老实说......我什至会将角度注射剂包装成一个全局变量injectables,例如injectables.$http , injectables.$timeout

以上是关于如何使用带有角度依赖注入的打字稿继承的主要内容,如果未能解决你的问题,请参考以下文章

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

如何在 Loopback 4(打字稿)中调用具有依赖注入的类的方法?

在打字稿中带有参数类型的角度 ui-state

带有打字稿的角度材料设计

带有打字稿的 Angular 5 websocket 示例

带有打字稿的嵌套角度指令