2012-10-31 70 views
5

我意識到TypeScript編譯器試圖保持對普通的舊JavaScript的正確性,因爲TypeScript確實是JavaScript。但是,Intellisense將其解釋爲「this」關鍵字與運行時實際解決的內容之間存在脫節。例如,請考慮以下打字稿Ajax調用:

getAgencies() { 
      var self = this;   
      $.ajax(liveString + "/Home/GetSupportedAgencies", 
      { 
       type: "GET", 
       contentType: "application/json; charset=utf-8", 
       dataType: "json", 
       error: Utilities.Logger.displayAjaxError, 
       success: this.onGetAgenciesComplete 
      }); 

     } 

及其相應的回調:

onGetAgenciesComplete(agencies) { 
       var self = this; 
        if (agencies == null) 
         Utilities.Logger.displayErrorOnLogConsole("There was an error retrieving supported agencies. Refresh site and try again."); 
        else { 
         $.each(agencies, function (i, a) { 
          self._indexViewModel.agencies.push({ name: a.Name, fullName: a.FullName, shortName: a.ShortName, bbox: a.BBox, countryCode: a.CountryCode }); 
         }); 

         if (Modernizr.geolocation) { 
          navigator.geolocation.getCurrentPosition(
           function (position) { 
            self.initMapPage(position, self); 
           }, 
           function (error) { 
            Utilities.Logger.displayErrorOnLogConsole("Oops, we could not get your location at his time. Please try later."); 
           }); 
         } 
         else { 
          Utilities.Logger.displayErrorOnLogConsole("Sorry, your browser does not return location information."); 
          self.getBusRoutes(self.agencyName); 
         } 


         // end of initialization 
        } 
       } 

現在,當我將鼠標懸停在行「無功自我=本」的打字稿源文件中onGetAgenciesComplete,變量「self」的Intellisense定義表示它是HomePageViewModelBase類型,其中HomePageViewModelBase是包含上述方法的類。

生成的JavaScript對於上述情況如下:

,當在HomePageViewModelBase.prototype.onGetAgenciesComplete執行變量「自我」
HomePageViewModelBase.prototype.getAgencies = function() { 
      var self = this; 
      $.ajax(liveString + "/Home/GetSupportedAgencies", { 
       type: "GET", 
       contentType: "application/json; charset=utf-8", 
       dataType: "json", 
       error: Utilities.Logger.displayAjaxError, 
       success: this.onGetAgenciesComplete 
      }); 
     }; 
     HomePageViewModelBase.prototype.onGetAgenciesComplete = function (agencies) { 
      var self = this; 
      if(agencies == null) { 
       Utilities.Logger.displayErrorOnLogConsole("There was an error retrieving supported agencies. Refresh site and try again."); 
      } else { 
       $.each(agencies, function (i, a) { 
        self._indexViewModel.agencies.push({ 
         name: a.Name, 
         fullName: a.FullName, 
         shortName: a.ShortName, 
         bbox: a.BBox, 
         countryCode: a.CountryCode 
        }); 
       }); 
       if(Modernizr.geolocation) { 
        navigator.geolocation.getCurrentPosition(function (position) { 
         self.initMapPage(position, self); 
        }, function (error) { 
         Utilities.Logger.displayErrorOnLogConsole("Oops, we could not get your location at his time. Please try later."); 
        }); 
       } else { 
        Utilities.Logger.displayErrorOnLogConsole("Sorry, your browser does not return location information."); 
        self.getBusRoutes(self.agencyName); 
       } 
      } 
     }; 

被解析成什麼樣子了AjaxContext而不是HomePageViewModelBase的一個實例。這是預期的行爲還是我應該報告這是一個錯誤?

回答

6

是的,你應該把它作爲一個bug報告給它們,因爲$.ajax()中的this是指$.ajax()對象本身。

如果你想出去轉轉它,這樣它的作品,你的成功的功能更改爲:

success: self.onGetAgenciesComplete 

或者,如果你this靜置類,只需使用背景方法$就

$.ajax({ 
    context: this, 
    // now *this* will come from the previous scope, 
    // which in your case, is your class "HomePageViewModelBase" 

    // now that we know for certain what -this- refers to 
    success: this.onGetAgenciesComplete 
}); 
+0

很好的回答 - 設定背景的作品。在提交bug之前,請考慮以下問題:當函數可以在許多不同的上下文中調用時,編譯器如何正確推斷「this」的上下文。我相信它基於直接調用函數的假設顯示正確的上下文,而不是從其他地方回調的上下文中。 – Fenton

+0

我同意,如果有的話,這是很好的做法(如果有的話,但也是爲了可讀性),以明確這個'this'的背景應該在這裏。我想@Kenji的觀點是,它不應該知道它是'$ .ajax'本身,因爲它是如何在jQuery中工作的? –

+0

@mcpDESIGNS,這是一個很好的解釋,謝謝。我從來不知道$ .ajax上下文是更好的解決方案。雙倍感謝。你在我的文章中也是正確的,intellisense不應該在$ .ajax中引用「This」到HomePageViewModel的一個實例。 –

3

至於任何(包括智能感知)靜態分析而言,的onGetAgenciesComplete背景下的我sHomePageViewModelBase永遠都會;除了在運行時,上下文將通過顯式內部jQuery.ajax上下文綁定動態設置。 Intellisense可以確定上下文會動態改變的唯一方法是實際執行該代碼路徑,但即使這樣做也會導致模糊:哪個上下文是正確的上下文?

如果您在其他地方「借用」某種方法進行一次性通話,該怎麼辦? Intellisense應該使用該呼叫站點來確定上下文嗎?也許不是...

HomePage.prototype.onGetAgencies.call({ some other context }, ...); 

(縮短了可讀性。)