2016-08-10 124 views
1

考慮以下角度服務:

app.factory('myService', function($http) 
{ 
    var service = 
    { 
     someArray: [], 
     updatePendingIds: function() 
     { 
      console.log(this); 
      $http.get("/get-stuff"). 
       then(function(response) 
       { 
        console.log(this); // someArray is not here! 
       }); 
     } 
    } 
} 

在第一的console.log,產生的角承諾對象之前,「這」是服務對象本身,預期。也就是說,它會有一個關鍵的「someArray」。

但第二個控制檯日誌返回這個作爲$窗口對象。兩個問題:

  1. 爲什麼這個$ window,而不是服務對象?
  2. 如何將服務對象傳遞給$ http promise?

回答

1

這是因爲您創建了一個新的環境,當你創建傳遞給承諾then方法的功能:

then( function(response) // new function context 

你需要該功能結合到你需要的對象。

var handleResponse = function(response) { 
    console.log(this); 
}; 

$http.get("/get-stuff").then(handleResponse.bind(this)); 
+0

的作品。也試過以下內容,創建了「handleResponse」函數作爲服務的成員,但仍然沒有綁定。必須實際調用綁定。例如「handleResponse:function(){...}」,然後是「$ http.get(url).then(this.handleResponse.bind(this));」驚訝的需要「綁定(這)」。爲什麼? –

+0

@RafaelBaptista這是一個常見的JavaScript誤解,因爲函數是第一類對象。執行一個函數,範圍例如'this.handleResponse()'不同於訪問包含函數的對象屬性,例如'this.handleResponse'。訪問屬性爲您提供了交給'.then'回調函數的第一類函數,但是當執行回調函數時,它不再具有範圍。 (我希望這是有道理的;這個概念很難在評論框中解釋:)) – Stephen

+0

其實,我期待的術語是「上下文」而不是範圍。這個博客解釋得很好:http://ryanmorr.com/understanding-scope-and-context-in-javascript/ – Stephen