在 ES6 中将纯 class 注入 angular 1.x 应用程序的正确方法
Correct way to inject pure class into angular 1.x application in ES6
一位同事声称这是将纯 ES6 JavaScript class 注入 Angular 的错误方法。很好奇有没有更好的方法(更正确)?
顺便说一句,将注入的依赖项(本例中的$timeout
)附加到实例是否更好(为什么更好)?例如,this._$timeout = $timeout
在构造函数中。我个人认为在这种情况下这样做没有任何优势。
class.factory.js
let ClassFactory = function($timeout) {
// Factory function that simply returns class constructor.
class MyClass {
constructor(a, b) {
// contrived class
this.a = a;
this.b = b;
this.c = null;
}
applyChange() {
// contrived class method
const SELF = this;
$timeout(() => {
SELF.c = SELF.a + SELF.b;
});
}
}
return MyClass ;
};
ClassFactory.$inject = ['$timeout'];
export default ClassFactory;
app.module.js
import ClassFactory from './factories/class.factory';
import AppService from './services/app.service';
export default angular.module('myApp', [])
.factory('ClassFactory', ClassFactory)
.service('AppService', AppService);
稍后,我们可能会在其他地方使用某些服务或控制器中的 class 来构造新的 MyClass 实例。
app.service.js
class AppService {
// contrived usage of our dependency injected pure class.
constructor(ClassFactory) {
this.array = [];
this._ClassFactory = ClassFactory;
}
initialize(a, b) {
// We can instantiate as many "MyClass" objects as we need.
let myClass = new this._ClassFactory(a, b);
this.array.push(myClass);
}
static serviceFactory(...injected) {
AppService.instance = new AppService(...injected);
return AppService.instance;
}
}
AppService.serviceFactory.$inject = ['ClassFactory'];
export default AppService.serviceFactory;
此时 $timeout
是 class 属性 还是局部变量并不重要。
用工厂函数包装 class 不适合 ES6 开发,无法导出和扩展它。需要工厂的事实可能表明设计问题。
像这样的class可以通过依赖注入获取依赖(在common sense中)。当 class 构造函数也应该使用非依赖参数调用时,这是很常见的事情:
export class MyClass {
constructor($timeout, a, b) {
this._$timeout = $timeout;
...
}
}
...
obj = new MyClass($timeout, a, b);
如果有多个依赖,可以提供$injector
个依赖,而不是所有的依赖:
export class MyClass {
constructor($injector, a, b) {
this._$timeout = $injector.get('$timeout');
...
}
}
...
obj = new MyClass($injector, a, b);
也有可能是设计问题导致了对$timeout
的依赖,通过解决可以避免依赖。从上面的代码中不清楚为什么 MyClass
应该使用 $timeout
触发摘要,它的逻辑不包含任何需要这样做的内容。这是使用 MyClass
实例并将其绑定到视图或任何摘要的代码的责任。
一位同事声称这是将纯 ES6 JavaScript class 注入 Angular 的错误方法。很好奇有没有更好的方法(更正确)?
顺便说一句,将注入的依赖项(本例中的$timeout
)附加到实例是否更好(为什么更好)?例如,this._$timeout = $timeout
在构造函数中。我个人认为在这种情况下这样做没有任何优势。
class.factory.js
let ClassFactory = function($timeout) {
// Factory function that simply returns class constructor.
class MyClass {
constructor(a, b) {
// contrived class
this.a = a;
this.b = b;
this.c = null;
}
applyChange() {
// contrived class method
const SELF = this;
$timeout(() => {
SELF.c = SELF.a + SELF.b;
});
}
}
return MyClass ;
};
ClassFactory.$inject = ['$timeout'];
export default ClassFactory;
app.module.js
import ClassFactory from './factories/class.factory';
import AppService from './services/app.service';
export default angular.module('myApp', [])
.factory('ClassFactory', ClassFactory)
.service('AppService', AppService);
稍后,我们可能会在其他地方使用某些服务或控制器中的 class 来构造新的 MyClass 实例。
app.service.js
class AppService {
// contrived usage of our dependency injected pure class.
constructor(ClassFactory) {
this.array = [];
this._ClassFactory = ClassFactory;
}
initialize(a, b) {
// We can instantiate as many "MyClass" objects as we need.
let myClass = new this._ClassFactory(a, b);
this.array.push(myClass);
}
static serviceFactory(...injected) {
AppService.instance = new AppService(...injected);
return AppService.instance;
}
}
AppService.serviceFactory.$inject = ['ClassFactory'];
export default AppService.serviceFactory;
此时 $timeout
是 class 属性 还是局部变量并不重要。
用工厂函数包装 class 不适合 ES6 开发,无法导出和扩展它。需要工厂的事实可能表明设计问题。
像这样的class可以通过依赖注入获取依赖(在common sense中)。当 class 构造函数也应该使用非依赖参数调用时,这是很常见的事情:
export class MyClass {
constructor($timeout, a, b) {
this._$timeout = $timeout;
...
}
}
...
obj = new MyClass($timeout, a, b);
如果有多个依赖,可以提供$injector
个依赖,而不是所有的依赖:
export class MyClass {
constructor($injector, a, b) {
this._$timeout = $injector.get('$timeout');
...
}
}
...
obj = new MyClass($injector, a, b);
也有可能是设计问题导致了对$timeout
的依赖,通过解决可以避免依赖。从上面的代码中不清楚为什么 MyClass
应该使用 $timeout
触发摘要,它的逻辑不包含任何需要这样做的内容。这是使用 MyClass
实例并将其绑定到视图或任何摘要的代码的责任。