如何在不使用构造函数注入的情况下获取EventAggregator实例

时间:2017-01-05 14:23:46

标签: typescript dependency-injection aurelia eventaggregator

我有一个看起来像这样的课程:

@inject(EventAggregator)
export class LootStack {
    stack: Array<Item.Loot> = [];

    constructor(private eventAggregator: EventAggregator) {
        this.eventAggregator.subscribe(MonsterKilled, () => {
            this.stack.push(new Item.Gold()); 
            this.stack.push(new Item.Weapon("Thunderfury, Blessed Blade of the Windseeker"));
        });
    }

    takeItem(lootItem: Item.Loot){
        this.eventAggregator.publish(lootItem.take()) <--- returns specific message
        this.stack.remove(lootItem);
    }
}

调用takeItem()时,我想根据点击的项目类型发布消息。我通过在项目实例上获取take()方法返回正确的消息而没有让项目知道EventAggregator,这样做了一种方法。

Gold然后实现如下:     take() { return new GoldTaken(this) };

然后Weapon实现如下:     take() { return new WeaponTaken(this) };

然后我立即通过知道EA的viewmodel发布它。

如果项目本身可以发布此消息,那将更好更清楚,但为了获得EventAggregator我只知道通过构造函数注入正确的实例。这并不是那么令人向往,因为我不想在每次新的和物品时都通过这个。

我是否有办法在项目实例的take方法中获取正确的EventAggregator单例?

2 个答案:

答案 0 :(得分:3)

您可以自己注入事件聚合器。

new Item.Gold(this.eventAggregator)

另一种选择是使用Aurelia的DI容器来创建项目并允许DI容器为您注入事件聚合器。您可能希望在此之后设置name属性。

以下是一个例子:https://gist.run?id=e1f5a3159a1a7464140f5e3b0582c18e

<强> app.js

import {inject, Container} from 'aurelia-framework';
import {Weapon} from './weapon';

@inject(Container)
export class App {

    constructor(container){ 
      const weapon = container.get(Weapon);

      weapon.name = 'Thunderfury, Blessed Blade of the Windseeker';

      console.log(weapon);
    } 
}

<强> weapon.js

import {inject} from 'aurelia-framework';
import {EventAggregator} from 'aurelia-event-aggregator';

@inject(EventAggregator)
export class Weapon {
  name = '';
  constructor(ea) {
    this.ea = ea;
  } 
}

答案 1 :(得分:0)

只是一个快速更新,以显示最终的建议如何。很高兴直接调用items take方法,现在没有一些奇怪的返回消息。

@autoinject
export default class ItemFactory {
    constructor(private eventAggregator: EventAggregator) { }

    buildGold(): Item.Gold {
        let newGold = new Item.Gold(this.eventAggregator);
        newGold.value = Dice.d20();
        newGold.template = "gold";
        return newGold;
    }

    buildWeapon(name: string): Item.Weapon {
        let newWeapon = new Item.Weapon(this.eventAggregator);
        newWeapon.name = name;
        newWeapon.damage = Dice.d20();
        newWeapon.template = "weapon";
        return newWeapon;
    }
}

然后我可以从项目中做到这一点:

@autoinject
export class LootStack {
    stack: Array<Item.Loot> = [];

    constructor(private eventAggregator: EventAggregator, private itemFactory: ItemFactory) {
        this.eventAggregator.subscribe(MonsterKilled, () => {
            this.stack.push(itemFactory.buildGold()); 
            this.stack.push(itemFactory.buildWeapon("Thunderfury, Blessed Blade of the Windseeker"));
        });
    }

    takeItem(lootItem: Item.Loot){
        lootItem.take();
        this.stack.remove(lootItem);
    }
}

[Github Changeset]