手动注入服务

Ami*_*mit 23 angular

我有分量B,C,D从类继承A.

我想在课堂上使用一个服务A,但我不知道如何注入它,而不是从孩子那里注入它.

我尝试的是正常注入: constructor(pageName: string = null, translate: TranslateService) { 但是当我super()构建类时A,它会抛出错误,因为我没有提供第二个参数.

有没有办法使用Angular 2注入父类?

我被迫使用的Angular版本是:2.2.1

编辑:

一些示例案例:我有很多页面,每个页面都可以显示一个加载器.我不想每次都注入加载器,而是从每个页面管理加载器,我想:

export class BaseComponent {
    constructor(private loader: LoadingService) {}

    showLoading() {
        this.loader.show();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后从组件本身继承:

@Component({
    selector: "page-login",
    providers: [UsersService],
    templateUrl: "login.html"
})
export class LoginPage extends BaseComponent {
    constructor(private usersService: UsersService) {
        super();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在LoginPage有一个showLoading来自它的父方法.

Mik*_*One 45

您可以使用服务定位器服务来解决此问题.这将很容易让你得到任何服务,并在你的父类中使用它,而不必通过他们的孩子注入它们(因为这可能是一个痛苦).

所以要使用它,创建一个简单的类locator.service.ts:

import {Injector} from "@angular/core";

export class ServiceLocator {
    static injector: Injector;
}
Run Code Online (Sandbox Code Playgroud)

app.module.ts中导入此服务:

import {ServiceLocator} from './locator.service';
Run Code Online (Sandbox Code Playgroud)

然后在你的模块文件(app.module.ts?)的构造函数中,初始化这个东西,这样你就可以在任何地方使用它:

export class AppModule {
    constructor(private injector: Injector){    // Create global Service Injector.
        ServiceLocator.injector = this.injector;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,要在超类(BaseComponent)中使用它,只需导入ServiceLocator即可

import {ServiceLocator} from './locator.service';
Run Code Online (Sandbox Code Playgroud)

并使用它像:

export class BaseComponent {
    public loader;
    constructor() {
        this.loader = ServiceLocator.injector.get(LoadingService)
    }

    showLoading() {
        this.loader.show();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您已将服务注入到可扩展父级中,并且它可以在子组件中使用,而无需在super()中传递它.

  • 应该没有。它使用实际的 Angular 注入器,该注入器在内部也用于进行依赖注入。 (2认同)
  • 这是公认的反模式。但这个解决方案特别有价值,因为在打字稿世界中,大量的基本构造函数参数可能会让派生类和 super 感到烦恼。特别是对于 UI 组件来说,让服务获取 UI 依赖项并不有利。 (2认同)
  • 从 Angular 14 开始,这个答案就变得有点陈旧了。Angular 现在具有注入功能,这是一个更好的解决方案。 (2认同)

Mar*_*nov 10

对于 Angular 14 及以上版本,有以下inject()函数:

import {inject} from '@angular/core'

export class BaseComponent {
  public loader;
  
  constructor() {
    this.loader = inject(LoadingService)
  }

  showLoading() {
    this.loader.show();
  }
}
Run Code Online (Sandbox Code Playgroud)
export class LoginPage extends BaseComponent {
  constructor(private usersService: UsersService) {
    super();
  }
}
Run Code Online (Sandbox Code Playgroud)

这种方式LoadingService将在您的两个(父和子)组件中可用,并且UsersService仅在您的子组件中可用。

如果您LoadingService只想在 中可用BaseComponent,只需设置即可private loader