2015-11-06 202 views
1

我想我错过了这里的理解相当丰富的东西,所以也许有一点解释也是非常有帮助的。TypeScript自定义事件侦听器

我有一个类,因为这样的:

class Entity { 
    protected pos: number = [0,0]; 

    ... 

    public setPos(x: number, y: number) { 
     this.pos = [x, y]; 
    } 
} 

,并希望类似

class EntityPositionListener { 
    //do stuff when an Entity position changes 
} 

我也有Entity类的后裔。因此,任何时候任何后裔EntityEntity本身都会更改pos变量(在给定的实例中),我想知道它以便我可以更新地图上的位置,以及捕获实例以便我可以从理论上来说,对这个例子做其他事情。

我注意到Firefox有这个Object.watch()命令,我发现有人在另一个问题上发布了一个“跨浏览器”的解决方案 - 无济于事 - 而且我已经尝试在类中“包装”Entity类后启动阶段,但后者只是最终覆盖Entity类或创建一个无限循环,所以我显然在某处丢失了点。如果包装是答案,我如何在TypeScript中做到这一点? JS版本创建了一个循环或没有工作。

//This created an infinite loop in runtime, but more importantly overwrote the Entity class 
function EntityListener(name) { 
    cout(name); 
} 
var oldEntity = Entity; 
function Entity(name) { 
    if (typeof EntityListener === "function") { 
     EntityListener(name); 
    } 

    oldEntity(name); 
} 

理想情况下,我想,听取他们对给定类几件事情 - 比如在游戏更新循环 - 只是用于演示这种特殊情况下。我发现了无数的链接,其中很多是JS,而不是明确的TypeScript,所以我真的很喜欢TypeScript解决方案和一些解释。我从根本上不理解如何去做这件事。

编辑

如果这是一个更好的版本问题,也许更简单地说,我怎么听Entity.setPos()的被称为?

回答

1

Object.observe将最有可能droppedObject.watch仅在Gecko中支持,所以不要在代码中使用它,除非您只定位到Firefox。

这意味着你必须编写自己的事件发射。您可以使用打字稿getter和setter如果你喜欢他们:

class Entity { 
    private entitityListener:EntityPositionListener; 
    private _pos:number[] = []; 

    get pos():number[] { 
     return this._pos; 
    } 
    set pos(value:number[]) {    
     this._pos = value; 

     if (this.entitityListener) { 
      this.entitityListener.reportEvent('pos', value); 
     } 
    } 
} 

class SuperEntity extends Entity { 

} 

let superEntity = new SuperEntity(); 
superEntity.pos = [1,2]; // this will call 'this.entitityListener.reportEvent()' and you don't need superEntity.setPos([1,2]); 

其中transpiles到:

var __extends = (this && this.__extends) || function (d, b) { 
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 
    function __() { this.constructor = d; } 
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 
}; 
var Entity = (function() { 
    function Entity() { 
     this._pos = []; 
    } 
    Object.defineProperty(Entity.prototype, "pos", { 
     get: function() { 
      return this._pos; 
     }, 
     set: function (value) { 
      this._pos = value; 
      if (this.entitityListener) { 
       this.entitityListener.reportEvent('pos', value); 
      } 
     }, 
     enumerable: true, 
     configurable: true 
    }); 
    return Entity; 
})(); 
var SuperEntity = (function (_super) { 
    __extends(SuperEntity, _super); 
    function SuperEntity() { 
     _super.apply(this, arguments); 
    } 
    return SuperEntity; 
})(Entity); 
var superEntity = new SuperEntity(); 
superEntity.pos = [1, 2]; 

您可以使用Object.defineProperty()定义getter和setter方法,这意味着你可以定义设定器包含一个调用EntityListener方法。

+0

是否有可能更改此代码,使EntityPositionListener随时侦听在不修改setter函数的情况下调用Entity [set]?我对这个解决方案的保留意见是,我必须回过头来修改函数来激活侦听器中的功能,而不是让侦听器对任何称为该函数的类的实例进行操作。或者这是不可能的? – Matt

+0

我已经更新了答案。说实话,我认为你会找到一种方法来做你想做的事。但是,它迟早会伤及IMO。我曾经做过一些疯狂的事情,所以我从我自己的经历谈起。 :-) –

+1

你可以使用TypeScript装饰器吗? HTTP://计算器。com/questions/29775830/how-to-implement -a-typescript-decorator可能是您的问题的合理解决方案。 –

相关问题