首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >角4中抽象类的动态、多提供者

角4中抽象类的动态、多提供者
EN

Stack Overflow用户
提问于 2017-11-22 13:59:46
回答 2查看 2.9K关注 0票数 0

我使用一个抽象类来显示来自不同来源的一些数据。在抽象类中注入每个源以在组件中显示数据。

这是我的组件,它使用抽象类获取数据:

代码语言:javascript
运行
复制
    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服务:

代码语言:javascript
运行
复制
@Injectable()
export abstract class AbstractclassService {


  public onMessage(msg: string): void {
    console.log("Testing");
  }

}

现在,我没有弄明白如何在useValue中注入不同的源?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-22 16:17:16

提供者中的使用价值不是用例的好方法。

Source1-Service和Source2-Service必须是扩展抽象类的类。之后,您将您的服务注入两个不同的提供者。

当类扩展抽象类时,扩展类必须定义方法onMessage (此处)。

因此,您的组件可以如下所示:

代码语言:javascript
运行
复制
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以获得更多信息。

票数 1
EN

Stack Overflow用户

发布于 2021-05-13 14:48:03

对于类似的问题,我通过拥有一个接口和一个InjectionToken列表来解决它。这有点过分,但这允许了大量的灵活性,并且可以适用于其他问题。

在共享模块中设置默认搜索服务之后,可以提供多个自定义实现(组件/模块/服务)。而不必显式注入(如此引用)所有可能的实现。

接口和默认实现

代码语言:javascript
运行
复制
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创建服务实现列表

代码语言:javascript
运行
复制
 // 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'));

默认服务实现的提供程序

代码语言:javascript
运行
复制
   providers: [
      ...
      // Default implementation service
      {
         provide: SearchServiceTokens.get('default'),
         useClass: DefaultSearch
      }
   ]

自定义实现(可能在另一个模块上)

代码语言:javascript
运行
复制
export class Component1Search implements ISearch {
    searchByTerm(textInput: string) { console.log("component1 search by term"); }
    searchByObject(objInput: Object) { console.log("component1 search by object"); }
}

为自定义实现添加令牌

代码语言:javascript
运行
复制
SearchServiceTokens.set('component1', new InjectionToken<ISearch>('component1'));

添加提供程序

代码语言:javascript
运行
复制
   providers: [
      ...
      // Other implementation service
      {
         provide: SearchServiceTokens.get('component1'),
         useClass: Component1Search
      }
   ]

最后,在一个组件中,全球服务.

代码语言:javascript
运行
复制
    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));
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47436583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档