在Angular通用服务中解析通用参数

时间:2019-03-12 15:40:24

标签: angular typescript dependency-injection

我有一个班级结构,需要一个BaseModel和很多ChildModels。像这样

// BaseModel type

import { Injectable } from '@angular/core';

@Injectable()
export class BaseModel { 
    constructor() {
    }

    public _instanceUrl(): string {
        return '';
    };

    public url(): string {
        return 'BASE_URL_' + this._instanceUrl();
    };
}

// ChildModel type

import { BaseModel } from './base-model';
import { Injectable } from '@angular/core';

@Injectable()
export class ChildModel extends BaseModel {
    constructor() {
        super();
    }

    public _instanceUrl(): string {
        return "CHILD_URL";
    }
}

// BaseService type

import { Injectable} from '@angular/core';
import { BaseModel } from '../models/base-model';

@Injectable()
export class BaseService<T extends BaseModel> {

    private url: string; 
    constructor(private childInstance: T) { 
    } 

    public getUrl() {
        return this.childInstance.url();
    }
}

这是我的AppModule实现:

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    HttpClientModule,
    BrowserModule,
    AppRoutingModule,
    ServicesModule
  ],
  providers: [BaseService],
  bootstrap: [AppComponent]
})
export class AppModule { }

这是我使用该服务的地方

import { Component } from '@angular/core';
import { BaseService } from './modules/services/base-service/base-service.service';
import { ChildModel } from './modules/services/models/child-model';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less']
})
export class AppComponent {
  title = 'angular-test';
  preventAbuse = false;

    constructor(private baseService: BaseService<ChildModel>) {
    }

    testHttp() {
        console.log(this.baseService.getUrl());
    }
}

我需要知道 Angular 是否有可能为T(在这种情况下为BaseService)的构造函数中提供正确的类型ChildModel。现在,我收到一条错误消息,说它不能提供构造函数参数。

  

未捕获的错误:无法解析BaseService的所有参数:   (?)。

如果我从BaseService的构造函数中删除了该参数,则该服务创建成功。问题不是注入BaseService,而是注入T类型的BaseService构造函数参数。而且,我可能有数百个子类,所以我想避免全部提供它们。不过,我不确定这是否可能。

我正在使用最新版本的Angular和Typescript

Angular CLI: 7.3.4
Angular: 7.2.7
typescript: 3.2.4

这里是Stackblitz

的链接

1 个答案:

答案 0 :(得分:0)

一个简单的解决方案是使用Injection of Generic Services in Angular

建议的工厂模式
providers: [{
 provide: 'baseService',
 useFactory: (childModel: ChildModel) => (new BaseService<ChildModel>(childModel)),
 deps: [ChildModel]
}]

constructor(@Inject('baseService') private baseService: BaseService<ChildModel>) { 
  console.log(baseService.getUrl()); // output "BASE_URL_CHILD_URL"
}