Angular2:如何将同一服务的两个实例注入多个组件? [英] Angular2: How to inject two instances of the same service into multiple components?

查看:25
本文介绍了Angular2:如何将同一服务的两个实例注入多个组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个如下所示的 Angular 服务:

@Injectable()导出类剪贴板{构造函数(私有倍数:多个,私有 di:DI,私有注入:注入,私有事物:事物){}//剪贴板有本地状态:私有 isCut:布尔值;私贴:英雄;切(英雄:英雄){this.isCut = true;this.toPaste = 英雄;}复制(英雄:英雄){this.isCut = false;this.toPaste = 英雄;}粘贴(位置:位置){//很多非常复杂的逻辑}canPaste(potentialLocation:位置){//很多非常复杂的逻辑}}

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

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

@Component({...})导出类 HeroTable {构造函数(私有剪贴板:剪贴板){}cutHero(英雄:英雄):无效{this.clipboard.cut(英雄);}}

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

  1. 用户剪辑《蝙蝠侠》
  2. 用户拖动 &将超人"放到新位置
  3. 用户尝试粘贴蝙蝠侠",但不幸的是剪贴板已被拖放污染.

我可以创建一个名为 DragDrop 的新类来扩展剪贴板:

@Injectable()导出类 DragDrop 扩展剪贴板{//拖放行为与剪贴板相同.请//不要覆盖这里的任何行为.这门课是一个黑客//获取剪贴板的第二个可注入实例.}

这允许我像这样更新 HeroTable:j

@Component({...})导出类 HeroTable {构造函数(私有剪贴板:剪贴板,私有 dragDrop:DragDrop){}cutHero(英雄:英雄):无效{this.clipboard.cut(英雄);}dragHer(英雄:英雄):无效{this.dragDrop.cut(英雄);}}

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

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

<小时>

我发现了这个问题:Angular2:如何使用同一服务的多个实例?这看起来非常相似,但我希望根据我提供的详细信息,我可能会得到略有不同的响应.

解决方案

没有很多方法可以做到这一点.我相信它们包含在引用的问题中,并且 此处.

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

<预><代码>...//Ng 模块供应商: [{ 提供:剪贴板,使用值:剪贴板 }]

导出类 HeroTable {私人剪贴板:剪贴板;私人拖放:剪贴板;构造函数(剪贴板:剪贴板){this.clipboard = 新剪贴板;this.dragDrop = 新剪贴板;}...}

对于带有依赖项的 Clipboard 可注入类,它是

@Injectable()类 DragDropClipboard {}...//Ng 模块供应商: [剪贴板,{ 提供:DragDropClipboard,useClass:剪贴板}]

导出类 HeroTable {构造函数(私有剪贴板:剪贴板,私有 dragDrop:DragDropClipboard){}...}

没什么问题

@Injectable()class DragDropClipboard 扩展 Clipboard {}

无论如何都应该有第二个提供者的占位符,至少在这种情况下输入是正确的,但它可能会创建更详细的输出.

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:

  1. User cuts 'Batman'
  2. User drags & drops 'Superman' to a new location
  3. 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 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.

这篇关于Angular2:如何将同一服务的两个实例注入多个组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆