问题
Suppose that I have an Angular Service that looks like this:
@Injectable()
export class Clipboard {
constructor(private multiple: Multiple, private di:DI, private injected:Injected, private things: Things){}
// The clipboard has local state:
private isCut: boolean;
private toPaste: Hero;
cut(hero: Hero){
this.isCut = true;
this.toPaste = hero;
}
copy(hero: Hero){
this.isCut = false;
this.toPaste = hero;
}
paste(locaction: Location){
// Lots of really complex logic
}
canPaste(potentialLocation: Location){
// Lots of really complex logic
}
}
Currently I have several components that uses the Clipboard Service.
When you right click on a hero you can copy/cut them. Later, in the same component or a different component, you can paste the hero. Something like this:
@Component({
...
})
export class HeroTable {
constructor(private clipboard: Clipboard){}
cutHero(hero: Hero): void {
this.clipboard.cut(hero);
}
}
I now want to add drag and drop to my components. Interestingly, the canPaste
, paste
, cut
and copy
methods are identical for drag and drop, however I need to use a separate instance of the clipboard to prevent the following scenario:
- User cuts 'Batman'
- User drags & drops 'Superman' to a new location
- User attempts to paste 'Batman' but unfortunately the clipboard has been polluted by the drag-n-drop.
I could create a new class called DragDrop
that extends the Clipboard:
@Injectable()
export class DragDrop extends Clipboard{
// Drag and Drop behaves identically to the Clipboard. Please
// don't override any behaviour here. This class is a hack to
// get a second injectable instance of Clipboard.
}
This allows me to update the HeroTable like this: j
@Component({
...
})
export class HeroTable {
constructor(private clipboard: Clipboard, private dragDrop: DragDrop){}
cutHero(hero: Hero): void {
this.clipboard.cut(hero);
}
dragHer(hero: Hero): void {
this.dragDrop.cut(hero);
}
}
This also allows me to use the two instances of the Clipboard in another component and tell which is which. I need to make sure that all components know which Clipboard should be used for Cut/Paste and which should be used for drag/drop.
Unfortunatly, this solution feels like a hack. Is there an Angular blessed way to do this?
I found this question: Angular2: How to use multiple instances of same Service? which seems very similar, however I am hoping that given the details that I am providing, I may get slightly different responses.
回答1:
There are not so many ways to do this. I believe they are covered in the cited question and also here.
For Clipboard
injectable class without dependencies, it is
...
// NgModule
providers: [
{ provide: Clipboard, useValue: Clipboard }
]
and
export class HeroTable {
private clipboard: Clipboard;
private dragDrop: Clipboard;
constructor(Clipboard: Clipboard){
this.clipboard = new Clipboard;
this.dragDrop = new Clipboard;
}
...
}
For Clipboard
injectable class with dependencies, it is
@Injectable()
class DragDropClipboard {}
...
// NgModule
providers: [
Clipboard,
{ provide: DragDropClipboard, useClass: Clipboard }
]
and
export class HeroTable {
constructor(private clipboard: Clipboard, private dragDrop: DragDropClipboard) {}
...
}
There's nothing wrong with
@Injectable()
class DragDropClipboard extends Clipboard {}
There should be a placeholder for the second provider any way, at least the typing will be correct in this case, but it will likely create more verbose output.
来源:https://stackoverflow.com/questions/39862994/angular2-how-to-inject-two-instances-of-the-same-service-into-multiple-componen