2014-09-02 6 views
6

Ho creare un UserService come segue:Annullamento di richiesta GET al server utilizzando 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'); 
}]); 

Dai commenti si può vedere che quello che sto cercando di realizzare è ogni volta che una richiesta GET viene eseguita tramite questo servizio utilizzando Restangular la cache locale viene controllata e se la cache restituisce un oggetto viene esteso nell'elemento restangular. Il flusso che si desidera ottenere è quello di annullare la richiesta al server quando viene trovato un oggetto cache per quella richiesta.

Tuttavia senza fortuna il metodo addResponseInterceptor viene eseguito anche se l'oggetto è stato trovato nella cache.

Esistono soluzioni per annullare la richiesta al server durante una richiesta "Get"?

Grazie! :)

risposta

3

Un modo per procedere sarebbe annullarlo tramite httpConfig. Restangular fornisce oggetto httpConfig come parametro nel metodo addFullRequestInterceptor. È possibile utilizzare che come nel seguente:

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

Spero che questo aiuti.

+0

Ciao, la richiesta è ancora in corso come indicato in questo numero: https://github.com/mgonto/restangular/issues/589. –

+0

Ho creato un jsfiddle poiché il codice aggiornato non rientra nella casella del commento ..... http: //jsfiddle.net/bop5nv1w/. Grazie :) –

+0

Ho provato ad usarlo in una delle mie app e funziona. Una differenza da notare è che, ho impostato la logica nella sezione angular.module ('ABC'). Config (...) usando RestangularProvider.addFullRequestInterceptor (...). Anche se non sono sicuro del perché questo farebbe la differenza, ma vale la pena provare. Sfortunatamente, non posso testare il tuo codice. Se si potesse creare un campione funzionante in cui si sta effettuando una chiamata al server, sarei lieto di esaminarlo. – CMR

0

È possibile decorare $ http per impedire più richieste allo stesso URL. Uso Restangular $ http, non è necessario aggiungere fullRequestIntercepter per annullare la richiesta, poiché ciò impedisce la richiesta prima di inviare.

$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

ho risolto il problema specifico di restituire i dati memorizzati nella cache se disponibili attraverso un'istanza CacheFactory angolare-cache semplicemente cambiando le impostazioni httpConfig nel RequestInterceptor. Esempio illustrato di seguito:

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; 
}); 
Problemi correlati