我使用一个抽象类来显示来自不同来源的一些数据。在抽象类中注入每个源以在组件中显示数据。
这是我的组件,它使用抽象类获取数据:
import {AbstractclassService} from '../../../../abstractclass.service';
import {Source2-Service} from '../../../../Source2.service';
import {Source1-Service} from '../../../../Source1.service';
@Component({
selector: 'app-gauge',
templateUrl: './gauge.component.html',
providers: [
{
provide: AbstractclassService,
useValue: Source1-Service , Source2-Service
multi: true
}
],
styleUrls: ['./gauge.component.css']
})
export class GaugeComponent implements OnInit {
data = [
{
name: 'test',
value: 'test'
}
];
constructor( public abstractclassService: AbstractclassService ) {}
ngOnInit () {
this.abstractclassService.onMessage = (msg: string) => {
this.data = [{name: 'test', value: msg}];
};
}
这是我的abstract-class服务:
@Injectable()
export abstract class AbstractclassService {
public onMessage(msg: string): void {
console.log("Testing");
}
}
现在,我没有弄明白如何在useValue中注入不同的源?
发布于 2017-11-22 16:17:16
提供者中的使用价值不是用例的好方法。
Source1-Service和Source2-Service必须是扩展抽象类的类。之后,您将您的服务注入两个不同的提供者。
当类扩展抽象类时,扩展类必须定义方法onMessage
(此处)。
因此,您的组件可以如下所示:
import { Component, Inject } from '@angular/core';
import { Observable } from "rxjs"
abstract class AbstractClassService{
abstract onMessage(msg: string): {name: string, value: string}
}
class Source1-Service extends AbstractClassService{
onMessage(msg: string) {
return {name: "test", value: msg}
}
}
class Source2-Service extends AbstractClassService{
onMessage(msg: string) {
return {name: "test2", value: msg}
}
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
providers: [
{provide: "Impl1", useClass: Source1-Service},
{provide: "Impl2", useClass: Source2-Service}
]
})
export class AppComponent {
msg1: {name: string,value:string}[]
msg2: {name: string,value:string}[]
constructor(@Inject("Impl1") private service1:AbstractClassService,
@Inject("Impl2") private service2:AbstractClassService) {
this.msg1 = [this.service1.onMessage("msg1")]
this.msg2 = [this.service2.onMessage("msg2")]
}
}
获得完整代码:https://stackblitz.com/edit/angular-e8sbg8?file=app%2Fapp.component.ts
为进一步的
我认为在这种情况下使用抽象类不是个好主意。您应该更喜欢使用接口。
并且,我邀请您在这里阅读DI角文档:https://angular.io/guide/dependency-injection#providers以获得更多信息。
发布于 2021-05-13 14:48:03
对于类似的问题,我通过拥有一个接口和一个InjectionToken列表来解决它。这有点过分,但这允许了大量的灵活性,并且可以适用于其他问题。
在共享模块中设置默认搜索服务之后,可以提供多个自定义实现(组件/模块/服务)。而不必显式注入(如此引用)所有可能的实现。
接口和默认实现
export interface ISearch {
searchByTerm(textInput: string);
searchByObject(objInput: Object);
}
export class DefaultSearch implements ISearch {
searchByTerm(textInput: string) { console.log("default search by term"); }
searchByObject(objInput: Object) { console.log("default search by object"); }
}
使用InjectionToken创建服务实现列表
// Keep list of token, provider will give a implementation for each of them
export const SearchServiceTokens: Map<string, InjectionToken<ISearch>> = new Map();
// Add File service implementation token
SearchServiceTokens.set('default', new InjectionToken<ISearch>('default'));
默认服务实现的提供程序
providers: [
...
// Default implementation service
{
provide: SearchServiceTokens.get('default'),
useClass: DefaultSearch
}
]
自定义实现(可能在另一个模块上)
export class Component1Search implements ISearch {
searchByTerm(textInput: string) { console.log("component1 search by term"); }
searchByObject(objInput: Object) { console.log("component1 search by object"); }
}
为自定义实现添加令牌
SearchServiceTokens.set('component1', new InjectionToken<ISearch>('component1'));
添加提供程序
providers: [
...
// Other implementation service
{
provide: SearchServiceTokens.get('component1'),
useClass: Component1Search
}
]
最后,在一个组件中,全球服务.
searchService: ISearch;
constructor(private injector: Injector) {
// Use default
this.searchService = this.injector.get(SearchServiceTokens.get('default'));
}
setCustomServiceServiceByToken(customSearchServiceToken) {
// Use custom service
this.searchService = this.injector.get(SearchServiceTokens.get(customSearchServiceToken));
}
https://stackoverflow.com/questions/47436583
复制相似问题