Angular:如何从其他模块覆盖共享模块服务

时间:2019-04-10 12:08:39

标签: javascript angular typescript dependency-injection

我有多个模块,例如SchoolModuleUniversityModuleSharedModule

SharedModule具有BaseServiceSchoolModule提供者都扩展到的UniversityModule

现在,当我加载SchoolModule时,我希望BaseService得到schoolService的实现,而UniversityModule也是这样

结构

app
  -- SharedModule
       -- base.service
       -- secret.service uses base.service
       -- shared.component uses secret.service

  -- SchoolModule
       -- school.component uses shared.component
       -- school.service

 -- UniversityModule
        -- university.component uses shared.component
        -- university.service

StackBlitz

那么我如何通过依赖注入来实现呢?

3 个答案:

答案 0 :(得分:0)

您必须使用抽象方法getName()将基本服务类声明为抽象类

export abstract class BaseService{


    abstract getName(): string { return 'Base Service' }


}

export class SchoolService extends BaseService{

   getName(): string { return 'School Service' }

}

答案 1 :(得分:0)

不幸的是,如果没有模块之间的导入,Angular2不能从另一个模块中注入一个类,如果您需要延迟加载它,那么事情就无法进行。 有一个项目可以从另一个模块动态加载组件。 很难将其导入到您的项目中,但可以节省两次代码。
可以找到here这个项目。

答案 2 :(得分:0)

问题是,提供的SecretService是在UniversityModule中构建的一个版本,是App Module中最后导入的模块,因此,如果要使用SecretService正确更新BaseService,则必须在大学和学校组件中同时提供BaseService和SecretService,如下所示:在school.component.ts中:

import { SchoolService } from './school.service'
import { BaseService } from '../shared/base.service'
import { SecretService } from '../shared/secret.service'

    @Component({
      selector: 'app-school',
      template: `SchoolName :: <app-shared></app-shared>`,
      providers: [
        { provide: BaseService, useClass: SchoolService },
        SecretService]
    })
    export class SchoolComponent implements OnInit {

      constructor() { }

      ngOnInit() {
      }

    }

和在university.component.ts

import {  UniversityService } from './university.service'
import { BaseService } from '../shared/base.service'
import { SecretService } from '../shared/secret.service'


@Component({
  selector: 'app-university',
  template: `UniversityName :: <app-shared></app-shared>`,
  providers: [{ provide: BaseService, useClass: UniversityService },
  SecretService]
})
export class UniversityComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

但是为什么要在SecretService中包装基本服务,而直接在共享组件中使用BaseService?

在shared.component.ts中使用BaseService

import { Component, OnInit } from '@angular/core';
import { BaseService } from './base.service'
@Component({
  selector: 'app-shared',
  template: `{{name}}`
})
export class SharedComponent implements OnInit {

  name: string
  constructor(private ss: BaseService) {
    this.name = ss.getName()
  }

  ngOnInit() {
  }

}

使用BaseService,您可以解决此注入问题,而无需在SecretService上采取任何变通方法