2013-03-11 60 views
8

是否可以強制打字稿將方法放在實例上而不是原型上。我問這個問題是因爲我經常遇到有關原型方法會導致問題的「範圍」問題。強制打字稿將方法放在實例上而不是原型

編輯


例如從它似乎不一致的TS輸出,我保持FooAlert在FooViewModel功能,但在原型

方法openFooAlertDialogueAdd的js

var FooViewModel = (function() { 
    function FooViewModel (json) { 
     this.Foolert = ko.observable(); 

    } 
    FooViewModel.prototype.openFooAlertDialogueAdd = function() { 
     this.FooAlert = something; 
    }; 

Ts

class FooViewModel{ 
    FooAlert = KnockoutObservableAny 

     constructor(){ 
     this.FooAlert = ko.observable(); 
     } 
    openFooAlertDialogueAdd() { 
     this.FooAlert = something; 
    }; 

} 

回答

4

原型上的方法是在每個實例上可用的方法。

class Example { 
    constructor(private someProperty: string) { 

    } 

    method() { 
     return this.someProperty; 
    } 
} 

var exampleA = new Example('A'); 
var exampleB = new Example('B'); 
var exampleC = new Example('C'); 

console.log(exampleA.method()); // A 
console.log(exampleB.method()); // B 
console.log(exampleC.method()); // C 

每個實例將有somePropertymethod()複製到它的原型。您可以檢查此使用:

alert(exampleC.hasOwnProperty('someProperty') ? 'Yes' : 'No'); 

只有當實例沒有自己的財產了JavaScript都會走上去,任何依賴關係鏈中找到一個類上漲依賴鏈的屬性。

如果您提供的代碼在this範圍內遇到問題,我相信我們可以幫助您解決問題。

+0

我做了一個編輯:) – FutuToad 2013-03-11 15:12:24

+0

我想我必須做openFooAlertDialogueAdd = function等,因爲它給出了正確的Js輸出 – FutuToad 2013-03-11 15:15:28

+0

將輸出JS放在一邊 - 因爲我認爲不重要 - 可以你展示了範圍問題的一個例子?即我認爲你想解決問題,我把事情做成靜態的,但我認爲可能有更好的方法。靜態解決方法是在靜態關鍵字前加上''static openFooAlertDialogueAdd()...' – Fenton 2013-03-11 16:24:14

12

如果你有範圍問題我爲你感到不好兒子,我有99個問題,但這不是一個!

Steve的答案顯示了定義類方法的正確方法,這些方法將在每個實例上公開。但是,如果遇到範圍問題,這可能是由於您從另一個上下文中調用這些方法。例如,如果您使用Knockout並將這些方法中的一種綁定到click綁定,則Knockout將覆蓋當前綁定範圍的範圍,而不是您已定義該方法的範圍。

有兩種選擇可以防止這種範圍的丟失。

首先,您可以在構造函數中定義您的方法,以在實例上而不是在原型上顯示它們。

像:

class Greeter { 
    greet:() => string; 
    greeting: string; 

    constructor(message: string) { 
     this.greeting = message; 
     this.greet =() => { 
      return "Hello, " + this.greeting; 
     } 
    } 

其次,你可以使用=>語法範圍類的方法。

例子:

class Greeter { 
    greeting: string; 
    constructor() { 
     this.greeting: "Blabla"; 
    } 
    greet=() => { 
     alert(this.greeting); 
    } 
} 
+3

+1,以獲得有關敲除修改範圍的註釋。無法弄清楚什麼是錯的。 – 2013-05-03 16:50:26

+0

有沒有辦法告訴淘汰賽不這樣做?我想定義我的方法outsite構造函數,因爲它看起來更好:) – 2013-05-03 16:51:23

+0

@ s093294 AFAIK還有一種方法,它只能用於點擊處理程序。您可以使用'ko.contextFor(event.target)。$ root'來獲取剛纔單擊的項目的根作用域。 – thomaux 2013-05-14 06:51:57

0

看起來這是一個打字稿/淘汰賽的問題,因爲在@Anzeo他的回答,以及你的編輯指出。我已經解決了這個問題,把我的方法聲明放在構造函數中,但也使用了Knockout's Computed Observable documentation的「管理」這個''部分中指出的約定var self = this;。你TS碼看起來是這樣的:

class FooViewModel{ 
    FooAlert: KnockoutObservableAny; 
    openFooAlertDialogueAdd:() => void; 

    constructor(){ 
     var self = this; 
     self.FooAlert = ko.observable(); 
     self.openFooAlertDialogueAdd = function(){ 
      self.FooAlert('whatever your FooAlert observable takes'); 
     }; 
    } 
} 

不管會發生什麼範圍變更,圍繞self JavaScript的關閉使您不必擔心this變化。這應該可以解決你的問題。

+0

使用'=>'(箭頭或lambda函數)這個範圍複製給你,所以你不需要自己複製它。 – thomaux 2013-09-24 06:17:30

+0

@Anzeo,它會!感謝您指出了這一點。我認爲我更喜歡用自我約定的明確副本。但是,它確實搞亂了構造函數,所以我可能會更多地考慮使用lambda。 – DBueno 2013-09-24 21:02:51