2016-05-21 10 views
1

'this'コンテキストがtypescriptでどのように機能するのか理解できません。メソッドのクラスメンバーにアクセスできません。以下は、あなたが実際に実行コードとしてコンパイルされたJavaScript typescriptですコンパイラの出力があり、私のコード'this' typecriptコールバック関数内のスコープ

class adopterDetailCtrl { 
    public adopter: IAdopter; 
    public $router: any; 

    static $inject = ['app.common.services.AdopterService']; 
    constructor(private adopterService: app.common.services.IAdopterServices) { 
     this.adopter = null; 
    } 

    $routerOnActivate(next) { 
     if (next.params.id > 0) { 
      this.getAdopterById(next.params.id); 
     } 
    } 

    getAdopterById(adopterId: number): void { 
     var AdopterList = this.adopterService.getAdopterById(); 
     AdopterList.query({ id: adopterId }, (data: adopter.IAdopter[]) => { 
      this.adopter = data[0];//this.adopter is undefined here. this refers to 'window' 
     }); 
    } 

    setAdopter(data: IAdopter) { 
     this.adopter = data;//can access this.adopter 
    } 
} 

答えて

2

this文脈だけではJavaScriptのように、そのようtypescriptですでも同じです。その場合は

  1. は、おそらく、コールバックとしてgetAdopterByIdを渡しているFunction.prototype.bind function

arrow function

  • 使用を使用する:あなたは、この問題に対処するための2つの方法があり、JavaScriptで

    bindを使用すると簡単に解決できます。

    let myobj = new adopterDetailCtrl(...); 
    
    ... 
    
    someFunction(myobj.getAdopterById.bind(myobj)); 
    

    またCTORにおけるインスタンスのメソッドのための基準を変更することができる:

    メソッド宣言が空であり、実装が使用CTORに設定されている(1)

    class adopterDetailCtrl { 
        public adopter: IAdopter; 
        public $router: any; 
    
        static $inject = ['app.common.services.AdopterService']; 
        constructor(private adopterService: app.common.services.IAdopterServices) { 
         this.adopter = null; 
    
         this.getAdopterById = (adopterId: number) => { 
          var AdopterList = this.adopterService.getAdopterById(); 
          AdopterList.query({ id: adopterId }, (data: adopter.IAdopter[]) => { 
           this.adopter = data[0];//this.adopter is undefined here. this refers to 'window' 
          }); 
         } 
        } 
    
        $routerOnActivate(next) { 
         if (next.params.id > 0) { 
          this.getAdopterById(next.params.id); 
         } 
        } 
    
        getAdopterById: (adopterId: number) => void; 
    
        setAdopter(data: IAdopter) { 
         this.adopter = data;//can access this.adopter 
        } 
    } 
    

    お知らせ矢印機能。ここでは、this.getAdopterByIdにバウンドthis.getAdopterById.bind(this)を再割り当てのctorで

    (2)

    class adopterDetailCtrl { 
        public adopter: IAdopter; 
        public $router: any; 
    
        static $inject = ['app.common.services.AdopterService']; 
        constructor(private adopterService: app.common.services.IAdopterServices) { 
         this.adopter = null; 
    
         this.getAdopterById = this.getAdopterById.bind(this); 
        } 
    
        $routerOnActivate(next) { 
         if (next.params.id > 0) { 
          this.getAdopterById(next.params.id); 
         } 
        } 
    
        getAdopterById(adopterId: number): void { 
         var AdopterList = this.adopterService.getAdopterById(); 
         AdopterList.query({ id: adopterId }, (data: adopter.IAdopter[]) => { 
          this.adopter = data[0];//this.adopter is undefined here. this refers to 'window' 
         }); 
        } 
    
        setAdopter(data: IAdopter) { 
         this.adopter = data;//can access this.adopter 
        } 
    } 
    

    これらの両方の場合、getAdopterByIdメソッドをコールバックとして自由に渡すことができ、thisのスコープについて心配する必要はありません。矢印の機能上の

    別のノートで、これはES6の新機能であり、あなたがあなたのcompilation optionsES6ターゲットを選択しない場合、コンパイラは、実際にこの表記を使用することはありませんが、代わりに、この変換することである。

    class A { 
        private x: number; 
    
        fn(): void { 
         setTimeout(() => console.log(this.x), 1); 
        } 
    } 
    

    へ:

    var A = (function() { 
        function A() { 
        } 
        A.prototype.fn = function() { 
         var _this = this; 
         setTimeout(function() { return console.log(_this.x); }, 1); 
        }; 
        return A; 
    }()); 
    

    thisの範囲は_thisに保存され、コールバック関数に_this.xをuである。この方法this.xの代わりにsed。

  • 関連する問題