对不起,标题有点复杂。
我使用angular 1.x已经有几年了,最近我一直在研究在我正在重构的代码库(也是angular1.x)中使用typescript的可能性。目前,我很难思考如何创建类(和类族)的可注入依赖项,而不是构造函数的依赖项。
Angular非常倾向于用单例服务构建应用程序,但我发现这些单例服务在应用程序运行时的整个生命周期中经常会受到过时/不正确状态的污染,或者在服务公开的功能与其操作的数据之间创建不必要的划分。
因此,我非常喜欢的一种模式是使用angular的.factory()
来生成构造函数,以便在我的应用程序中的不同位置使用。在ES5和Angular的模块系统环境中,您可以执行如下操作:
angular.module('SomeApp', [])
.factory('BaseClass', baseClassFactory)
.factory('SubClass', subClassFactory);
baseClassFactory.$inject = ['$http'];
function baseClassFactory ($http) {
function BaseClass () {}
BaseClass.prototype = {
$http: $http
/* some additional implementation */
};
return BaseClass;
}
subClassFactory.$inject = ['BaseClass'];
function subClassFactory (BaseClass) {
function SubClass () {}
SubClass.prototype = Object.create(BaseClass.prototype);
angular.extend(SubClass.prototype, {
someNewMethod: function () {
this.$http.get('/some/url').then(function (data) {
/* some operation on the data to update this instance */
});
}
});
return SubClass;
}
最突出的一点是,我现在可以创建一个“类”家族,每个类都可以通过工厂函数中的初始化逻辑访问注入的依赖项。用于子类的工厂显式地为父类注入工厂的结果;我们被迫利用Angular的模块和DI系统来实现这一点,但是在没有其他东西的情况下,它工作得很好。
在上面的例子中,我可能会创建一个模型类,它的实例会公开原始数据以及保存/删除操作/what have you use
$http
。在我的应用程序的其他地方,我只需要注入我的一个类,我就可以顺利地new SubClass(someArgs).someNewMethod()
。在typescript(或者,我想,是普通的jane es6 js)中,这种依赖于angular模块和可注入组件的运行时依赖解析的模式是使用ts/es6模块系统和继承的重复工作。
对于singleton服务,或者我们希望将依赖项注入构造函数的任何其他类,都没有问题。事实上,互联网上有很多这样的例子:
class MyThing {
static $inject = ['$http'];
constructor(private $http: ng.IHttpService) {}
}
angular.module('asdf', []).service('myThing', MyThing);
即使对于
MyThing
的子类,这也非常有效。但是,我还没有找到一个好的方法,那就是实现我原来的js示例的效果。理想情况下,我可以声明一些类,这些类意味着在应用程序中有许多实例,但它们仍然具有可注入的依赖项。大致如下:
class BaseClass {
$http: ng.IHttpService;
constructor(not, injectables) {
/* i do not exist to be injected */
}
}
class SubClass extends BaseClass {
someMethod() {
return this.$http.get('/some/url');
}
}
这使得所需的
$http
可用于BaseClass
的所有实例,以及BaseClass
的所有实例子类,而无需执行繁琐的操作:angular.module('myModule', [])
.factory('BaseClass', baseClassFactory)
.factory('SubClass', subClassFactory)
baseClassFactory.$inject = ['$http'];
function baseClassFactory($http) {
BaseClass.prototype.$http = $http;
return BaseClass;
}
subClassFactory.$inject = ['$http'];
function subClassFactory($http) {
SubClass.prototype.$http = $http;
return SubClass;
}
当然,这是可行的,但它是许多额外的(容易出错的)样板文件。它还要求任何子类的作者敏锐地意识到父类指定的每个依赖项。
我希望这是有意义的。有人对如何解决这个问题有什么建议吗?
最佳答案
我认为它应该像在ES7中那样以类似的方式处理:
class BaseClass {
static $inject = ['$http'];
constructor(...args) {
(<any>this).constructor.$inject.forEach((service, index) => {
this[service] = args[index];
});
}
}
这样,子级可以通过调用
super()
继承依赖项或拥有自己的依赖项。关于angularjs - 使用TypeScript在Angular 1.x中的类级可注入(inject)依赖项?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33313849/