我有一个看起来像这样的课程:
@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单例?
答案 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);
}
}