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.
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 isand
For
Clipboard
injectable class with dependencies, it isand
There's nothing wrong with
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.