2014-09-02 49 views
6

我已創建一個UserService如下GET請求到服務器:取消使用Restangular

angular.module('nrApp').factory('userService', ['Restangular', 'UserModel', 'DSCacheFactory', function (Restangular, UserModel, DSCacheFactory) { 
    // Create a new cache called "profileCache" 
    var userCache = DSCacheFactory('userCache', { 
     maxAge: 3600000, 
     deleteOnExpire: 'aggressive', 
     storageMode: 'localStorage', // This cache will sync itself with `localStorage`. 
     onExpire: function (key, value) { 
      Restangular.oneUrl('users', key).get().then(function(data) { 
       userCache.put(key, data); 
      }); 
     } 
    }); 

    Restangular.extendModel('users', function(obj) { 
     return UserModel.mixInto(obj); 
    }); 

    Restangular.addRequestInterceptor(function(element, operation, what, url) { 
     if(operation === 'get') { 
      debugger; 
      //Check the cache to see if the resource is already cached 
      var data = userCache.get(url); 
      //If cache object does exist, return it 
      if(data !== undefined) { 
       angular.extend(element, data); 
      } 

      return element; 
     } 
    }); 

    Restangular.addResponseInterceptor(function(data, operation, what, url, response) { 
     //Cache the response from a get method 
     if(operation === 'get') { 
      debugger; 
      userCache.put(url, data); 
     } 

     //Unvalidate the cache when a 'put', 'post' and 'delete' is performed to update the cached version. 
     if (operation === 'put' || operation === 'post' || operation === 'delete') { 
      userCache.destroy(); 
     } 

     return response; 
    }); 

    return Restangular.service('users'); 
}]); 

從中可以看出該評論認爲,我試圖做到的,是每當通過該服務使用進行Get請求重新檢查本地緩存,並且如果緩存返回對象,則將其擴展到冗餘元素中。希望實現的流程是在爲該請求找到緩存對象時取消對服務器的請求。

但是沒有任何運氣,即使在緩存中找到對象,addResponseInterceptor方法仍會執行。

在'Get'請求期間是否有任何可能的解決方案來取消對服務器的請求?

謝謝! :)

回答

3

去解決這個問題的一種方法是通過httpConfig取消它。 Restangular爲您提供httpConfig對象作爲addFullRequestInterceptor方法中的參數。你可以使用如下所示:

RestangularProvider.addFullRequestInterceptor(function(element, operation, what, url, headers, params, httpConfig) { 
    ... 
    if found in cache { 
     var defer = $q.defer(); 
     httpConfig.timeOut = defer.promise; 
     defer.resolve(); 
    } 
    ... 
} 

希望這會有所幫助。

+0

嗨,請求仍在制定中,如本問題中所述:https://github.com/mgonto/restangular/issues/589。 – 2014-09-02 22:21:39

+0

我創建了一個jsfiddle,因爲更新的代碼不符合評論框..... http://jsfiddle.net/bop5nv1w/。 謝謝:) – 2014-09-02 22:26:04

+0

我試過在我的應用程序中使用它,它的工作原理。需要指出的一點是,我使用RestangularProvider.addFullRequestInterceptor(...)將邏輯設置在angular.module('ABC')。config(...)節中。雖然我不確定爲什麼這會有所作爲,但值得嘗試。不幸的是,我無法測試你的代碼。如果您可以在實際進行服務器調用的情況下提供工作示例,我很樂意查看它。 – CMR 2014-09-03 11:32:27

0

您可以修飾$ http以防止對同一網址發出多個請求。 Restangular使用$ http,不需要添加fullRequestIntercepter來取消請求,因爲這樣在發送之前阻止請求。

$provide.decorator('$http', function ($delegate, $cacheFactory, $rootScope) { 
    var $http = $delegate; 
    var customCache = $cacheFactory('customCache'); 
    var wrapper = function() { 
     var key = arguments[0].url; 
     var requestPromise = customCache.get(key); 
     if (!requestPromise){ 
      $rootScope.requestCount++; 
      requestPromise = $http.apply($http, arguments); 
      requestPromise.then(function(){ 
       customCache.remove(key); 
      }); 
      customCache.put(key, requestPromise) 
     } 
     return requestPromise; 
    }; 

    Object.keys($http).filter(function (key) { 
     return (typeof $http[key] === 'function'); 
    }).forEach(function (key) { 
     wrapper[key] = function() { 
      return $http[key].apply($http, arguments); 
     }; 
    }); 

    return wrapper; 
}); 

Example here

1

我解決了,如果可以通過角緩存CacheFactory例如,通過簡單地在RequestInterceptor改變httpConfig設置返回緩存數據的特定問題。示例如下所示:

angular.module('App') 
.factory('Countries', function (Restangular, CacheFactory, $q) { 

    var countryCache; 
    var countryService; 

    // Check to make sure the cache doesn't already exist 
    if (!CacheFactory.get('countryCache')) { 
     countryCache = CacheFactory('countryCache', { maxAge: 60 * 60 * 1000 }); 
    } 

    if (!countryService) { 
     countryService = Restangular.service('countries'); 

    Restangular.addFullRequestInterceptor(function(element, operation, what, url, headers, params, httpConfig) { 

      if (what === 'countries') { 
       switch (operation) { 
        case 'getList': 
         httpConfig.cache = countryCache; 
         break; 

        default: 
         break; 
       }    
      } 

      return { 
       element: element, 
       headers: headers, 
       params: params, 
       httpConfig: httpConfig 
      }; 

     }); 

    } 

    return countryService; 
});