Angular2:如何将同一服务的两个实例注入多个组件?

时间:2016-10-04 22:55:32

标签: angular angular2-services angular2-providers

假设我有一个看起来像这样的Angular服务:

@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
    }

}

目前我有几个使用剪贴板服务的组件。

右键单击英雄时,您可以复制/剪切它们。之后,在同一个组件或不同的组件中,您可以粘贴英雄。像这样:

@Component({
    ...
})
export class HeroTable {

    constructor(private clipboard: Clipboard){}

    cutHero(hero: Hero): void {
        this.clipboard.cut(hero);
    }
}

我现在想要拖放到我的组件。有趣的是,canPastepastecutcopy方法对于拖放操作是相同的,但我需要使用剪贴板的单独实例来防止以下情况:

  1. 用户削减' Batman'
  2. 用户拖动&滴滴'超人'到新的位置
  3. 用户试图粘贴' Batman'但不幸的是,剪贴板被拖放污染了。
  4. 我可以创建一个名为DragDrop的新类,它扩展了剪贴板:

    @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.
    
    }
    

    这允许我像这样更新HeroTable: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);
        }
    }
    

    这也允许我在另一个组件中使用剪贴板的两个实例并告诉哪个是哪个。我需要确保所有组件都知道哪个剪贴板应该用于剪切/粘贴,哪些应该用于拖放。

    不幸的是,这个解决方案感觉就像一个黑客。是否有一种Angular有福的方式来做到这一点?

    我发现了这个问题:Angular2: How to use multiple instances of same Service?看起来非常相似,但是我希望根据我提供的细节,我可能会得到稍微不同的回答。

1 个答案:

答案 0 :(得分:2)

没有太多方法可以做到这一点。我相信引用的问题以及here都涵盖了它们。

对于没有依赖关系的Clipboard可注入类,它是

...
// NgModule
providers: [
  { provide: Clipboard, useValue: Clipboard }
]

export class HeroTable {
    private clipboard: Clipboard;
    private dragDrop: Clipboard;

    constructor(Clipboard: Clipboard){
      this.clipboard = new Clipboard;
      this.dragDrop = new Clipboard;
    }
    ...
}

对于具有依赖关系的Clipboard可注入类,它是

@Injectable()
class DragDropClipboard {}

...
// NgModule
providers: [
  Clipboard,
  { provide: DragDropClipboard, useClass: Clipboard }
]

export class HeroTable {
    constructor(private clipboard: Clipboard, private dragDrop: DragDropClipboard) {}
    ...
}

没有错
@Injectable()
class DragDropClipboard extends Clipboard {}

第二个提供者应该有一个占位符,至少在这种情况下输入是正确的,但它可能会产生更详细的输出。