max*_*xhb 76 inheritance inject typescript typescript1.8 angular
我有一组angular2组件,应该都会注入一些服务.我的第一个想法是,最好创建一个超级类并在那里注入服务.然后我的任何组件都会扩展该超类,但这种方法不起作用.
简化示例:
export class AbstractComponent {
constructor(private myservice: MyService) {
// Inject the service I need for all components
}
}
export MyComponent extends AbstractComponent {
constructor(private anotherService: AnotherService) {
super(); // This gives an error as super constructor needs an argument
}
}
Run Code Online (Sandbox Code Playgroud)
我可以通过MyService在每个组件中注入并使用该参数进行super()调用来解决这个问题,但这肯定是某种荒谬的.
如何正确组织我的组件,以便他们从超类继承服务?
Gün*_*uer 60
我可以通过在每个组件中注入MyService并使用该参数进行super()调用来解决这个问题,但这肯定是某种荒谬的.
这并不荒谬.这是构造函数和构造函数注入的工作原理.
每个可注入类都必须将依赖项声明为构造函数参数,如果超类也具有依赖项,则这些类也需要在子类的构造函数中列出,并通过super(dep1, dep2)调用传递给超类.
绕过注射器并获得依赖性势在必行具有严重的缺点.
它隐藏了使代码难以阅读的依赖关系.
它违反了一个熟悉Angular2 DI如何工作的人的期望.
它打破了离线编译,生成静态代码以替换声明性和命令性DI,以提高性能并减少代码大小.
max*_*xhb 54
更新的解决方案,通过使用全局注入器来防止生成myService的多个实例.
import {Injector} from '@angular/core';
import {MyServiceA} from './myServiceA';
import {MyServiceB} from './myServiceB';
import {MyServiceC} from './myServiceC';
export class AbstractComponent {
protected myServiceA:MyServiceA;
protected myServiceB:MyServiceB;
protected myServiceC:MyServiceC;
constructor(injector: Injector) {
this.settingsServiceA = injector.get(MyServiceA);
this.settingsServiceB = injector.get(MyServiceB);
this.settingsServiceB = injector.get(MyServiceC);
}
}
export MyComponent extends AbstractComponent {
constructor(
private anotherService: AnotherService,
injector: Injector
) {
super(injector);
this.myServiceA.JustCallSomeMethod();
this.myServiceB.JustCallAnotherMethod();
this.myServiceC.JustOneMoreMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
这将确保MyService可以在任何扩展AbstractComponent的类中使用,而无需在每个派生类中注入MyService.
这个解决方案有一些缺点(请参阅我原始问题下面的@GünterZöchbauer的Ccomment):
有关Angular2中依赖注入的书面解释,请参阅此博客文章,这有助于我解决问题:http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular- 2.HTML
我没有手动注入所有服务,而是创建了一个提供服务的类,例如,它会注入服务。然后将此类注入派生类并传递给基类。
派生类:
@Component({
...
providers: [ProviderService]
})
export class DerivedComponent extends BaseComponent {
constructor(protected providerService: ProviderService) {
super(providerService);
}
}
Run Code Online (Sandbox Code Playgroud)
基类:
export class BaseComponent {
constructor(protected providerService: ProviderService) {
// do something with providerService
}
}
Run Code Online (Sandbox Code Playgroud)
提供服务类:
@Injectable()
export class ProviderService {
constructor(private _apiService: ApiService, private _authService: AuthService) {
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,现在可以使用inject() https://angular.io/api/core/inject以非常简单的方式使用 Angular v14 实现这一点,因为您现在可以在构造函数外部的“字段初始值设定项”中设置依赖项完全。
我使用了一些简单的令牌依赖项DOCUMENT作为LOCALE_ID示例。
import { DOCUMENT } from '@angular/common';
import { inject } from '@angular/core';
export abstract class AbstractComponent {
abstractDependency = inject(DOCUMENT);
}
Run Code Online (Sandbox Code Playgroud)
import { Component, inject, LOCALE_ID } from '@angular/core';
import { AbstractComponent } from './abstract.component';
@Component({
selector: 'my-app',
template: '{{ abstractDependency }} {{ myDependency }}',
})
export class MyComponent extends AbstractComponent {
myDependency = inject(LOCALE_ID);
}
Run Code Online (Sandbox Code Playgroud)
实例:https://stackblitz.com/edit/angular-ivy-zvlx1d ?file=src/app/my.component.ts
| 归档时间: |
|
| 查看次数: |
29123 次 |
| 最近记录: |