角度依赖提供者

时间:2019-06-16 14:45:31

标签: angular

我有一个参数为PATH的服务,在模块的提供程序中设置此服务时需要设置此参数。

当我将此服务注入该模块的某个组件中并且调用该服务的任何方法时,参数PATH将已经设置。

我关注了这份文档https://angular.io/guide/dependency-injection-providers,但并没有帮助我。


@Injectable()
export class MyService {

  PATH: string;

  constructor(
    private otherService: OtherService,
  ) {
  }

  getAll() {
   return this.httpClient.post<InquiryResponse<any>>(this.PATH, request);
   // FYI: this is only for example purposes
  }

@NgModule({
  declarations: [
    SomeComponent,
  ],
  imports: [
    CommonModule,
  ],
  providers: [
    MyService  // < --- I need to set the parameter PATH here
  ]
})
export class MyModule {

export class MyComponent implements OnInit {


  constructor(
    private myService: MyService
  ) { }

  ngOnInit() {
    this.myService.getAll();  // <-- when call getAll the PATH already be set before in module
  }

3 个答案:

答案 0 :(得分:2)

有四个选项。可能更多,但是我想这些是最常用的一次,并且根据您的用例,您可以决定需要什么。

1。使用INJECTION_TOKEN

使用这样的令牌,您可以使用AppModule的providers数组将常量注入到您的服务中:

首先创建一个注入令牌文件:

path.token.ts

export const PATH = new InjectionToken<string>('PathToSomethingDescription');

app.module.ts

@NgModule({
  // ...
  providers: [
    { provide: PATH, useValue: 'https://foo-bar' } 
  ]
})
export class AppModule {}

my.service.ts

export class MyService {
  constructor(@Inject(PATH) path: string) {}
}

然后,您可以在服务内部使用this.path,它将具有提供程序定义中提供的值。如果您希望某些模块中的此InjectionToken有所不同,也可以覆盖此


2。使用角度cli中的环境文件

您可以使用环境文件插入常量:

environment.ts

export const environment = {
  // ...
  path: 'https://foo-bar'
};

my.service.ts

export class MyService {
  PATH: string = environment.path;
}

3。创建一个tree-shakable提供者

my-service.ts

@Injectable({
  providedIn: 'root',
  useFactory: () => new MyService('https://foo-bar'),
})
export class MyService {
  constructor(readonly PATH: string) {}
}

4。在各个模块中使用useFactory创建提供程序

如果在模块之间需要不同的值,则不应这样做,而应从功能模块中的@Injectable中添加useFactory:

random-feature.module.ts

@NgModule({
  providers: [
    // ...
    { provide: MyService, useFactory: () => new MyService('https://foo-bar') }
  ]
})
export class RandomFeatureModule {}

my-service.ts

export class MyService {
  constructor(readonly PATH?: string) {}
}

然后通常将其注入您需要的位置。请注意,尽管您将获得同一服务的不同实例。这可能会导致意外行为

答案 1 :(得分:1)

您想要的是工厂供应商。它允许您参数化服务创建https://angular.io/guide/dependency-injection-providers#factory-providers

答案 2 :(得分:0)

至少有几种方法可能最简单,因为使用某些路径参数会为此创建InjectionToken:

// in service you add token definition:
export const PATH = new InjectionToken<string>('PATH');

@Injectable()
export class MyService {
  constructor(
    @Inject(PATH) private path: string,
  ) {
  }
  ...
}
// in module import token and add value for it
import { PATH, MyService } from './service';

@NgModule({
  ...
  providers: [
    MyService,
    {
      provide: PATH,
      useValue: 'some/path/value'
    },
  ]
})
export class MyModule {

Read more about InjectionToken