自定义通用组件构造函数的注入令牌?

问题描述 投票:0回答:1

我制作了一个通用材料自动完成功能,我想将其用于不同的 API 数据,例如国家、人物、职位等。这些数据中的每一个都具有共同的属性:id、name。因此,我定义了一个接口:

export interface AutocompleteValue {
    id?: number,
    name: string
}

我还使用服务来获取这些数据,每个服务都扩展相同的结构。总有一个

getAll()
方法来获取数据。为此,我使用了扩展的泛型类型。

export class APIService<GetType> {
    getAll(): Observable<T[]> {...};
}

最后,我有一个通用的自动完成角度材质组件可用于每种类型。

@Component({...})
export class AutoCompleteInput<Type extends AutocompleteValue, ServiceType extends GetAllProvider<Type>> implements ControlValueAccessor, MatFormFieldControl<Type | undefined> {
    ...
    constructor(protected service: ServiceType, ...) {}
    ...
}

如果我想在某个地方使用它:

export class PositionsAutoComplete extends AutoCompleteInput<GetDto, PositionService> {
    constructor(
        @Inject(POSITION_SERVICE_TOKEN) protected override service: PositionService, ...){}
}

原来我需要提供注入代币...

@Inject(POSITION_SERVICE_TOKEN)
export const POSITION_SERVICE_TOKEN = new InjectionToken<PositionService>('');
.

在app.component.ts中:

providers: [{ provide: POSITION_SERVICE_TOKEN, useClass: PositionService }]

到目前为止效果很好。但是,AutocompleteInput 还需要注入令牌,我不知道为什么?我在

AutoCompleteInput
的构造函数中出现以下错误:

类的参数“service”没有合适的注入令牌 “自动完成输入”。考虑使用@Inject装饰器来指定 注入令牌。(-992003)

更新:我对通用服务也有类似的问题,我只需从通用类中删除

@Injectable
装饰器即可解决问题。我认为这很相似,
@Component
实例化通用类,这需要一个
InjectionToken
。如果删除
@Component
,我将无法在通用类 (
autocomplete-input.component.html
) 中使用该模板。

angular typescript generics angular-material constructor-injection
1个回答
0
投票

您需要提供注入令牌,因为 Angular 不知道应该为 ServiceType 提供什么类。您是否有一项或多项扩展 getAllProvider 的服务?如果你有的话,直接提供即可。

如果你有很多,那么你就不能做你想做的事,至少不能以这种方式做。您必须在不同的组件中提供不同的服务,具体取决于某些组件需要什么服务

© www.soinside.com 2019 - 2024. All rights reserved.