2015-03-19 55 views
0

我正在嘗試爲http請求做一個緩存工廠,所以它不會使服務器爲同一請求做很多工作。但似乎我使用推遲的「吞下」數據的方式,我不知道爲什麼。Angularjs Factory延遲的數據消失

控制檯輸出如下:

數據獲取:
對象{狀態: 「OK」,數據:對象的errorMessage:空,異常:空}
成功
不確定

ImportFactory:

factory("importFactory", function ($http, $q, loggingService) { 
return{ 
    fetchedData: [], 
    cacheTransport: function (transportsId, data) { 
     this.fetchedData.push({"transportsId": transportsId, "data": data}); 
    }, 
    getImport: function (transportsId) { 
     var factory = this; 
     var deferred = $q.defer(); 
     var preFetchedTransport = this.findTransport(transportsId); 
     if (preFetchedTransport === null) { 
      console.log('fetching from backend'); 
      return $http.post("/import/create/" + transportsId).then(function (data) { 
       console.log('data fetched:'); 
       console.log(data); 
       factory.cacheTransport(transportsId, data); 
       deferred.resolve(data); 
      }); 
     } 
     preFetchedTransport = deferred.promise; 
     return preFetchedTransport; 
    }, 
    findTransport: function (transportsId) { 
     for (var i = 0; i < this.fetchedData.length; i++) { 
      var transportObj = this.fetchedData[i]; 
      if (transportObj.transportsId === transportsId) { 
       return transportObj.data; 
      } 
     } 
     return null; 
    } 
}; 

});

控制器

.controller('ImportController', function ($scope, $routeParams, importFactory){ 
    $scope.transportId = $routeParams.id; 
    importFactory.getImport($scope.transportId).then(function (successData) { 
     console.log('success'); 
     console.log(successData); 
    }, function (errorData) { 
     console.log('error'); 
     console.log(errorData); 
    }); 
+0

爲什麼不直接使用$ http的內置緩存,如$ http.post(url,{cache:true}) – 2015-03-19 12:25:48

+0

因爲我需要更新緩存。 – 2015-03-19 12:27:46

回答

1

你基本上需要這樣的:Demo here.

var cachedPromises = {}; 
return { 
    getStuff: function(id) { 
    if (!cachedPromises[id]) { 
     cachedPromises[id] = $http.post("/import/create/" + id).then(function(resp) { 
     return resp.data; 
     }); 
    } 
    return cachedPromises[id]; 
    } 
}; 

現在,當你獲取這些數據,你可以操縱它會被改變,當你在未來的訪問。

myService.getStuff(whatever).then(function(data) { 
    data.foo = 'abc'; 
}); 

//elsewhere 
myService.getStuff(whatever).then(function(data) { 
    console.log(data.foo); // 'abc' 
}); 

這裏有一個演示,做這個,還有一個視圖更新招(綁定的對象的視圖中的數據進來之前),以及如何你可以分別從高速緩存更改數據的想法,以防你想擁有原始數據和不斷變化的數據。 http://jsbin.com/notawo/2/edit

記得要避免那種令人討厭的諾言反模式。如果您已經有承諾,請使用它,而不是用$q創建另一個。 $http已經返回承諾,並且如果您正確使用它,承諾就足以滿足您的任何需求。

+1

再次非常感謝,向我展示了真正使用承諾的人:) – 2015-03-20 12:40:16

0

只是改變循環條件這個樣子的,然後進行測試,我認爲你的函數和推遲是做工精細,但循環不會發送正確的數據

for(var i = 0; i < this.fetchedData.length; i++) { 
     if (this.fetchedData[i].transportsId === transportsId) { 
      return this.fetchedData[i].data; 
     } 
    } 
    return null; 
} 
+0

它完全沒有。另外謝謝。 – 2015-03-19 12:37:47

0

你沒有定義的原因是你沒有從$ http.post()。then()中返回任何東西!

同樣在getImport()函數中,當傳輸已被緩存時,您將返回一個空承諾。您需要將其解析爲已經緩存的傳輸對象。

getImport: function (transportsId) { 
    var factory = this; 
    var deferred = $q.defer(); 
    var preFetchedTransport = this.findTransport(transportsId); 
    if (preFetchedTransport === null) { 
     console.log('fetching from backend'); 
     return $http.post("/import/create/" + transportsId).then(function (data) { 
      console.log('data fetched:'); 
      console.log(data); 
      factory.cacheTransport(transportsId, data); 
      return data;    //this was missing 
     }); 
    } 

    // resolve it with transport object if cached 
    deferred.resolve(preFetchedTransport); 
    return deferred.promise; 
},