[英]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的新手,我有两个服务DefaultService
和SpecialService
,应根据组件状态交替使用,我不知道是否可以通过更改其状态向其注入一个Singleton GeneralService
,使其在某种程度上类似于DefaultService
或SpecialService
实施。
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
假设SpecialService
和DefaultService
扩展了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: 只要改变false
到true
在这里:
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.