简体   繁体   English

如何动态更改角度服务的实现?

[英]How to dynamically change angular service implementation?

I'm new to Angular2 and and I have two services DefaultService And SpecialService that shoud be used alternatively according to a component state I don't know if I can Inject into my component a singleton GeneralService that somehow behave like DefaultService or SpecialService by changing its implementation. 我是Angular2的新手,我有两个服务DefaultServiceSpecialService ,应根据组件状态交替使用,我不知道是否可以通过更改其状态向其注入一个Singleton GeneralService ,使其在某种程度上类似于DefaultServiceSpecialService实施。

I have another idea to inject both services in generalService and delegate thier methods to the appropriate service. 我还有另一个想法,可以将两个服务都注入generalService并将它们的方法委托给适当的服务。

thanks to tell me how can I implement the first Idea if doable, or suggest me anothers. 感谢您告诉我,如果可行的话,我该如何实施第一个想法,或者提出另一个建议。

@Component({
  selector: 'my-app',
   templateUrl : './content.component.html'
})
export class AppComponent  { 
constructor(generalService : GenralService,injector : Injectot){}
@ViewChild(MySon)
    private mySon : MySon;
    state : State;

    onChangeState(newState : State):void{
        if(state = special)
        //this.generalService = this.injector.get('SpecialService');
        myson.updateplease();
    }
}

Assume SpecialService and DefaultService extends GeneralService 假设SpecialServiceDefaultService扩展了GeneralService

Your first idea is totally possible (if I understood it correctly). 您的第一个想法是完全可能的(如果我理解正确的话)。 The idea would be to create GeneralService as an interface and then create two services that inherit from this interface and implement its function. 想法是将GeneralService创建为接口,然后创建两个从该接口继承并实现其功能的服务。 Then, via the injector , you get a reference to the one you want. 然后,通过进injector获得所需参考。

Have a look at this plunker: http://plnkr.co/edit/rjghCDkc5jUjp1SSpjDK 看看这个矮子: http ://plnkr.co/edit/rjghCDkc5jUjp1SSpjDK

Just change the false to true in here: 只要改变falsetrue在这里:

if (false)
{
  this.service = this.injector.get(SpecialService);
}
else
{
  this.service = this.injector.get(DefaultService);
}

To see that the logged value in the "console" changes. 查看“控制台”中记录的值是否更改。 I put the initialization in ngOnInit but you could do it everywhere you want ;-) 我将初始化放在ngOnInit但是您可以在任何需要的地方进行;-)

The cleaner way would be to use an interface , so you will get intellisense! 较干净的方法是使用interface ,这样您将获得智能感知! :) :)

export interface IYourService {
  func1: (source: string, subString: string) => boolean;
  func2: () => void;
  func3: () => string;
}

@Injectable()
export class SuperService implements IYourService {
  public func1(source: string, subString: string): boolean {
    return true;
  }

  public func2(): void {
    console.log('SuperService: func2();');
  }

  public func3(): string {
    return "SuperService";
  }
}

@Injectable()
export class SpecialService implements IYourService {
  public func1(source: string, subString: string): boolean {
    return false;
  }

  public func2(): void {
    console.log('SpecialService: func2();');
  }

  public func3(): string {
    return "SpecialService";
  }
}

@Injectable()
export class GeneralService {

  public state = 'SuperService';

  constructor (
    private _superService: SuperService,
    private _specialService: SpecialService
  ) {}

  public get instance(): IYourService {
    if (this.state == 'SuperService') return this._superService;
    else return this._specialService;
  }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2 (click)="switchService()">Hello {{name}} - active service: {{ this._generalService.state }} - click me to switch it!</h2>
      <button (click)="labelFunc1.innerHTML = _generalService.instance.func1()">func1</button>
      <label #labelFunc1></label>
      <br />
      <button (click)="_generalService.instance.func2()">func1</button>
      <br />
      <button (click)="labelFunc3.innerHTML = _generalService.instance.func3()">func1</button>
      <label #labelFunc3></label>
    </div>
  `,
})
export class App {
  name:string;
  constructor(private _generalService: GeneralService) {
    this.name = 'Angular2'
  }

  private switchService() {
    if (this._generalService.state == 'SuperService') {
      this._generalService.state = 'SpecialService';
    }
    else this._generalService.state = 'SuperService';
  }
}

live demo: https://plnkr.co/edit/OM5nnAR0kzSeV24vKqL5?p=preview 现场演示: https : //plnkr.co/edit/OM5nnAR0kzSeV24vKqL5?p=preview

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM