如何在不使用构造函数注入的情况下获取 EventAggregator 实例
How to get EventAggregator instance without using constructor injection
我有一个 class 看起来像这样:
@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()
时,我想根据单击的项目类型发布消息。我通过在项目实例 return 上获取正确消息的 take()
方法,在不让项目知道 EventAggregator 的情况下共同破解了一种执行此操作的方法。
Gold
然后这样实现:
take() { return new GoldTaken(this) };
然后Weapon
是这样实现的:
take() { return new WeaponTaken(this) };
然后我立即通过了解 EA 的视图模型发布它。
如果项可以自己发布此消息会更好更清楚,但为了获得 EventAggregator,我只知道通过构造函数注入正确的实例。这不是很理想,因为我不想在每次更新和项目时都传递这个。
有没有办法让我从项目实例的 take 方法中获取正确的 EventAggregator 单例?
您可以自己注入事件聚合器。
new Item.Gold(this.eventAggregator)
另一种选择是使用 Aurelia 的 DI 容器来创建项目并允许 DI 容器为您将事件聚合器注入到它们中。您可能希望在此之后设置名称 属性。
举个例子: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;
}
}
只是一个快速更新,以显示最终推荐的结果。很高兴直接调用 items take 方法,现在不需要处理一些奇怪的 return 消息。
@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);
}
}
我有一个 class 看起来像这样:
@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()
时,我想根据单击的项目类型发布消息。我通过在项目实例 return 上获取正确消息的 take()
方法,在不让项目知道 EventAggregator 的情况下共同破解了一种执行此操作的方法。
Gold
然后这样实现:
take() { return new GoldTaken(this) };
然后Weapon
是这样实现的:
take() { return new WeaponTaken(this) };
然后我立即通过了解 EA 的视图模型发布它。
如果项可以自己发布此消息会更好更清楚,但为了获得 EventAggregator,我只知道通过构造函数注入正确的实例。这不是很理想,因为我不想在每次更新和项目时都传递这个。
有没有办法让我从项目实例的 take 方法中获取正确的 EventAggregator 单例?
您可以自己注入事件聚合器。
new Item.Gold(this.eventAggregator)
另一种选择是使用 Aurelia 的 DI 容器来创建项目并允许 DI 容器为您将事件聚合器注入到它们中。您可能希望在此之后设置名称 属性。
举个例子: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;
}
}
只是一个快速更新,以显示最终推荐的结果。很高兴直接调用 items take 方法,现在不需要处理一些奇怪的 return 消息。
@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);
}
}