角度6:延迟将服务/提供程序加载到另一个服务中

时间:2018-07-24 02:10:11

标签: dependency-injection angular6 angular-providers

由于孩子的知识,我试图将提供程序延迟加载到父级中。想象一下:

@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加载它。

这是一个测试: https://stackblitz.com/edit/angular-u8tbwx

1 个答案:

答案 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