I have a class that looks like this:
@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);
}
}
When takeItem()
is called I want to publish a message based on the type of item clicked. I have hacked together a way of doing this without having the item know of the EventAggregator by getting the take()
method on the item instance return the correct message.
Gold
is then implemented like this:
take() { return new GoldTaken(this) };
And Weapon
is then implemented like this:
take() { return new WeaponTaken(this) };
I then just publish this immediately via the viewmodel which is aware of the EA.
It would be nicer and clearer if the items could publish this message themselves, but in order to get the EventAggregator i only know of injecting the correct instance via the constructor. This is not so desireable as I dont want to have to pass this in every time i new up and item.
Is there a way for me to get the correct EventAggregator singleton from within my take method on the item instance?
You could inject the event aggregator in yourself.
new Item.Gold(this.eventAggregator)
Another option would be to use Aurelia's DI container to create the items and allow the DI container to inject the event aggregator in to them for you. You would probably want to set the name property after that.
Here's an example: https://gist.run?id=e1f5a3159a1a7464140f5e3b0582c18e
app.js
weapon.js