由于孩子的知识,我试图将提供程序延迟加载到父级中。想象一下:
@Injectable()
export class ServiceA {
constructor(
@Inject(MY_TOKEN)
private serviceB: ServiceBImpl
) { }
run() {
this.serviceB.b();
}
}
ServiceBImpl
仅仅是一个界面
export let MY_TOKEN = new InjectionToken<ServiceBImpl>('MY_TOKEN');
export interface ServiceBImpl {
b();
}
ServiceA
已加载到根AppModule
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [
ServiceA
],
bootstrap: [AppComponent]
})
export class AppModule { }
MY_TOKEN
已装入子注入器。但是,我不需要此组件中的MY_TOKEN
,而是请求ServiceA
。
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [
{ provide: MY_TOKEN, useClass: ServiceB }
]
})
export class AppComponent {
title = 'app';
constructor(
public serviceA: ServiceA
) {
// Does not work
this.serviceA.run();
}
}
这不起作用。
让我清楚一点,我不想在组件级别的提供程序中拥有ServiceA
,而是从AppModule
加载它。
答案 0 :(得分:0)
您要完成的工作面临的挑战是在根注入器处提供textView.setTextIsSelectable(true);
,无论出于何种目的和目的,它都会创建一个单例。因此,在构造android:textIsSelectable="true"
时,它仅需与该注射器中可用的任何东西一起工作-如果未提供ServiceA
,则它将中断。
我建议将ServiceA
设置为更多工厂,以便为您提供所需的灵活性。从您的Stackblitz示例中,其中MY_TOKEN
取决于ServiceA
,而ServiceA
取决于ServiceAA
:
ServiceB
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
providers: [
{ provide: MY_TOKEN, useClass: ServiceB }
]
})
export class AppComponent {
serviceAA: ServiceAA;
constructor(
private serviceA: ServiceA,
@Inject(MY_TOKEN) private serviceB: ServiceBImpl
) {
this.serviceAA = serviceA.createServiceAAWithB(serviceB);
}
}
实际上是createServiceAAWithB
。这种模式可能类似于new ServiceAA(serviceb)
叠加服务通过其@angular/cdk
方法生成叠加实例的方式,该方法基本上是工厂:https://github.com/angular/material2/blob/7.0.0/src/cdk/overlay/overlay.ts#L66。