2013-07-09 71 views
0

我們已經知道在使用Knockout時做var self = this是有用的,以避免事件處理程序中的問題。但是,我正在觀察Typescript中的奇怪行爲。以下是簡化的代碼示例。代碼中的「this」與執行過程中的「this」不匹配

<i class="icon-edit" data-bind="click: $parent.GetEditForm"></i> 
export class Foo 
{ 
    public ID: KnockoutObservable<Number>; 
} 

export class FooEditor 
{ 
    public Items: KnockoutObservableArray<Foo>; 

    public GetEditForm(item: Foo, event) 
    { 
     console.log(this); 
     console.log(item); 
    } 
} 

據Visual Studio中,thisFooEditoritem一個實例是Foo一個實例。但是,在執行過程中,thisitem都是指Foo的實例。 TypeScript在這裏有錯嗎?或者這是Knockout魔法的一部分?

回答

2

可以通過使用箭頭的功能,例如保持在打字稿當前詞法上下文:() =>

class Example { 
    private name = 'Example'; 

    constructor() { 
     window.setTimeout(() => { alert(this.name); }, 1000); 
    } 
} 

在這個例子中,因爲我們使用箭頭功能this.name將是「實施例」。如果你嘗試同樣具有正常的功能,你將失去的this背景:

class Example { 
    private name = 'Example'; 

    constructor() { 
     window.setTimeout(function() { alert(this.name); }, 1000); // undefined 
    } 
} 

引擎蓋下,打字稿引入了一個變量來存儲的範圍和函數中的替代品吧...

var _this = this; 
    window.setTimeout(function() { 
     alert(_this.name); 
    }, 1000); 
+0

不幸的是,當使用箭頭函數時,你不能再使用重載。我很願意現在沒有超載,我已經看到有關於CodePlex上的範圍問題的活動。 – Stijn

1

它的javascript如何工作,'這'是綁定到調用者。如果你想「這」是父母試試這個:

<i class="icon-edit" data-bind="click: $parent.GetEditForm.bind($parent,$data)"></i> 

綁定將綁定「這個」到你的情況$父第一個參數,然後通過$數據(富)作爲第一個參數。

+0

感謝您的信息。我會把這個轉到CodePlex上的TypeScript討論。 'self'似乎總是指'Window',訪問一個類屬性需要用'this.Bar'來完成,否則它不會被編譯,但是當然在執行過程中'this'指的是別的東西。這太可怕了。 – Stijn

+0

我不認爲TypeScript可以做任何事情,因爲畢竟TS給你的JavaScript,JavaScript的行爲方式。 –

+0

問題是,TypeScript給了我錯誤的信息。類型安全性消失,智能感知錯誤。所以我現在也可以寫JavaScript。 HTTPS://typescript.codeplex。com/discussion/449410 – Stijn

0

我遇到了同樣的問題,放鬆回調函數內的範圍。

我試過了箭頭函數,但仍然沒能保持範圍。

因此,足夠多的挖掘後,我想出了這個解決方案:

loadObject =() => { 
      var mySelf = this; 
      Phoria.Util.importGeometryWavefront({ 
       url: "app/js/models/phoria/teapot.obj", 
       scaleTo: 5, 
       fnSuccess: function (args) { mySelf.placeObject(mySelf,args) }, 
      reorder: false, 
      center: true 
     }); 
    } 


    placeObject = (mySelf,obj) =>{ 
     mySelf.entityTeapot= Phoria.Entity.create({ 
      points: obj.points, 
      polygons: obj.polygons, 
      style: { 
       specular: 0, 
       drawmode: "solid", 
       shademode: "lightsource", //gouraud 
       fillmode: "inflate" 
      } 
     }); 
     mySelf.scene.graph.push(this.entityTeapot); 
    }; 

我跟着這個答案Typescript + Jquery Ajax + this

的領先,但我不得不使用「自我」(它指向窗口)的一些問題。

最後,它似乎是攔截回調調用並將範圍注入它。

希望它有幫助, 雷納託

相關問題