我想知道如何初始化一个依赖于另一个服务的服务和一个用于在服务中实例化依赖关系的复杂对象。目前,我正在使用InjectionToken将复杂对象推送到服务中,但我需要动态地将不同的复杂对象推送到服务,具体取决于用户采用的路径。
为了演示这个问题,假设我有一个依赖于HelperService的InterestingService和一个包含用于实例化内部服务类的参数的对象:
...
@Injectable()
export class InterestingService {
interestingObject: InterestingObject;
constructor(private helperService: HelperService,
@Inject(PARMS) private parms: ParmsTemplate) {
// parms e.g. {value1: 'aaa', value2: [1,2,3]}
this.interestingObject = new InterestingObject(parms);
}
doSomething() {
this.interestingObject.doSomethingAwesome()
}
}
参数必须遵循特定格式:
export interface ParmsTemplate {
value1?: string,
value2: number[]
}
该服务由组件使用:
import { Component, OnInit } from '@angular/core';
import { InterestingService } from './interesting.service';
@Component({
selector: 'app-some-component',
templateUrl: './some.component.html',
styleUrls: ['./some.component.css']
})
export class SomeComponent implements OnInit {
constructor(public service: InterestingService) { }
ngOnInit() {
this.service.doSomething();
}
}
InjectorToken定义以及一系列预定义的配方包含在PARMS中:
import { Injectable } from '@angular/core';
import { InjectionToken } from '@angular/core';
import { ParmsTemplate } from './parms';
export const PARMS = new InjectionToken<ParmsTemplate> ('parms.for.interesting.objects');
export const RECIPE_1: ParmsTemplate = {
value1: 'aaa',
value2: [1,2,3]
}
export const RECIPE_2: ParmsTemplate = {
value1: 'bbb',
value2: [1,2,3,4,5,6,7]
}
export const RECIPE_3: ParmsTemplate = {
value2: [1,2]
}
在AppModule中初始化了InjectionToken:
...
import { RECIPE_1, RECIPE_2, RECIPE_3, PARMS } from './parms';
import { InterestingService } from './interesting.service';
import { HelperService } from './helper.service';
@NgModule({
declarations: [
SomeComponent
],
imports: [
BrowserModule,
FormsModule,
AppRoutingModule,
HttpClientModule
],
exports: [ ],
providers: [
InterestingService,
HelperService,
{
provide: PARMS, useValue: RECIPE_1
}
],
entryComponents: [ ],
bootstrap: [AppComponent]
})
export class AppModule { }
最后,定义路线:
...
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SomeComponent } from './some.component';
const routes: Routes = [
{ path: 'recipe1', component: SomeComponent },
{ path: '', redirectTo: '/', pathMatch: 'full' },
{ path: '**', redirectTo: '/'}
];
@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
这一切都很好,而且适用于一个食谱。我想做的是扩展我的路线以包括其他食谱:
...
const routes: Routes = [
{ path: 'recipe1', component: SomeComponent },
{ path: 'recipe2', component: SomeComponent },
{ path: 'recipe3', component: SomeComponent },
{ path: '', redirectTo: '/', pathMatch: 'full' },
{ path: '**', redirectTo: '/'}
];
...
问题是我的InjectionToken只能在AppModule中设置为一个值。
答案 0 :(得分:0)
最后,我重构了我的代码以消除对基于路由的数据的需求,而是创建了一个服务来保存预制的配方并初始化InterestingObject。我对这个解决方案感到非常高兴。
在此之前,我能够使用路线数据,但我不得不使用ActiveRoute和不同的路线事件来获取组件中的数据。虽然这很有效,但它影响了我创建动态配方和重用组件的能力,因为尝试将数据推送到路径中是很尴尬的。这项服务显然是正确答案。
我将我的预制食谱设置为共享服务的方法。不幸的是,我不得不将它们设置为实例方法,以便HTML中的表达式可以引用它们。我尝试将它们设为静态变量,但表达式似乎看不到服务上的静态,但是它们可以看到实例引用没有问题。