2015-11-06 144 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可能是您的問題的合理解決方案。 –

相關問題