1

次のような Angular Service があるとします。

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

コンポーネントにドラッグ アンド ドロップを追加したいと考えています。興味深いことに、、、canPasteおよびメソッドはドラッグ アンド ドロップと同じですがpaste、次のシナリオを防ぐために、クリップボードの別のインスタンスを使用する必要があります。cutcopy

  1. ユーザーが「バットマン」をカット
  2. ユーザーが「スーパーマン」を新しい場所にドラッグ アンド ドロップする
  3. ユーザーが「バットマン」を貼り付けようとしましたが、残念ながらクリップボードがドラッグ アンド ドロップによって汚染されました。

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);
    }
}

これにより、クリップボードの 2 つのインスタンスを別のコンポーネントで使用して、どちらがどちらであるかを判断することもできます。切り取り/貼り付けに使用するクリップボードとドラッグ/ドロップに使用するクリップボードをすべてのコンポーネントが認識していることを確認する必要があります。

残念ながら、このソリューションはハックのように感じます。これを行うAngularの祝福された方法はありますか?


この質問を見つけました: Angular2: 同じサービスの複数のインスタンスを使用するには? これは非常に似ているように見えますが、私が提供している詳細を考えると、わずかに異なる応答が得られることを願っています.

4

1 に答える 1

3

これを行う方法はそれほど多くありません。それらは引用された質問とここでもカバーされていると思います。

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

いずれにしても、2 番目のプロバイダーのプレースホルダーが必要です。少なくともこの場合、入力は正しくなりますが、より詳細な出力が作成される可能性があります。

于 2016-10-04T23:25:54.393 に答える