Angular2 - 注入需要初始化参数的服务

gt6*_*07a 26 dependency-injection angular

我有一项服务需要启动一些价值:

@Injectable()
export class MyService {
  private myVals: any;

  constructor(init : any) {
    this.myVals = init;
  }
}
Run Code Online (Sandbox Code Playgroud)

和消费者:

@Component(...)
export class MyComponent {
  private svc: MyService;
  constructor(private svc : MyService) {
  }
}
Run Code Online (Sandbox Code Playgroud)

那么有没有办法在"依赖注入期间"注入并将所需参数传递给MyService的构造函数?就像是:

constructor(private svc({ // init vales }) : MyService) {}
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过变量传递所有但有兴趣找到是否有办法从API执行此操作.

Ily*_*dik 18

Angular团队在这里推荐了一种官方方式.它基本上允许您注入静态类型的配置类.

我已成功实现它,这里是所有相关代码:

1) app.config.ts

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

export let APP_CONFIG = new OpaqueToken("app.config");

export interface IAppConfig {
    apiEndpoint: string;
}

export const AppConfig: IAppConfig = {    
    apiEndpoint: "http://localhost:15422/api/"    
};
Run Code Online (Sandbox Code Playgroud)

2) app.module.ts

import { APP_CONFIG, AppConfig } from './app.config';

@NgModule({
    providers: [
        { provide: APP_CONFIG, useValue: AppConfig }
    ]
})
Run Code Online (Sandbox Code Playgroud)

3) your.service.ts

import { APP_CONFIG, IAppConfig } from './app.config';

@Injectable()
export class YourService {

    constructor(@Inject(APP_CONFIG) private config: IAppConfig) {
             // You can use config.apiEndpoint now
    }   
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以在不使用字符串名称的情况下将配置注入到任何地方,并使用您的接口进行静态检查.

您当然可以进一步分离界面和常量,以便能够在生产和开发中提供不同的值,例如

  • 这适用于已知的静态值.我很好奇我是否可以告诉Angular使用构造函数(坚持模式)在运行时使用确定的值来实例化服务. (12认同)
  • 更新!! 在Angular4中,OpaqueToken已弃用,将被InjectionToken取代.InjectionToken允许传递泛型类型参数.1)/sf/ask/2890248511/ 2)https://arturas.smorgun.com/2017/06 /08/inject-environment-configuration-into-service-in-angular4.html (4认同)

Bla*_*mba 5

上面的答案已被弃用,因为angular 4 现在您可以像这样使用它:

import { NgModule, APP_INITIALIZER } from '@angular/core';

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: onAppInit1,
      multi: true,
      deps: [/* your dependencies */]
    },
    {
      provide: APP_INITIALIZER,
      useFactory: onAppInit2,
      multi: true,
      deps: [/* your dependencies */]
    }
  ]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用@Inject,解释如下

为您服务:

import {Inject, Injectable} from '@angular/core';
    
@Injectable({
  providedIn: 'root'
})

export class NgService {
    constructor (
       @Inject('paramId') private paramId: string
    ) { }
}
Run Code Online (Sandbox Code Playgroud)

然后,在您的组件中:

import { Component } from '@angular/core';

@Component({
  selector: 'app-demo',
  template: `
    <div"> </div>
  `,
   providers: [
    {provide: 'paramId', useValue: 'param-id'},
  ]
})

export class AppComponent {

  constructor(private ngService: NgService) { }

}
Run Code Online (Sandbox Code Playgroud)