AngularJS'de HTTP 'Get' hizmeti yanıtı önbelleğe alınıyor mu?


211

Veri nesnesi boş olduğunda ve veri nesnesini başarılı bir şekilde doldururken bir HTTP 'Get' isteği yapan özel bir AngularJS hizmeti oluşturabilmek istiyorum.

Bir dahaki sefere bu hizmet için bir çağrı yapıldığında, HTTP isteğini tekrar yapma yükünü atlamak ve bunun yerine önbelleğe alınmış veri nesnesini döndürmek istiyorum.

Mümkün mü?

Yanıtlar:


315

Angular's $ http yerleşik bir önbelleğe sahiptir . Dokümanlara göre:

cache - {boolean | Object} - HTTP yanıtının önbelleğe alınmasını etkinleştirmek veya devre dışı bırakmak için $ cacheFactory ile oluşturulan bir boolean değeri veya nesne . Daha fazla bilgi için $ http Önbellekleme konusuna bakın .

Boole değeri

Yani ayarlayabilirsiniz cacheiçin gerçek onun seçeneklerinde:

$http.get(url, { cache: true}).success(...);

veya yapılandırma türünü tercih ediyorsanız:

$http({ cache: true, url: url, method: 'GET'}).success(...);

Önbellek Nesnesi

Ayrıca bir önbellek fabrikası da kullanabilirsiniz:

var cache = $cacheFactory('myCache');

$http.get(url, { cache: cache })

$ CacheFactory kullanarak kendiniz uygulayabilirsiniz (özellikle $ resource kullanırken elverişli ):

var cache = $cacheFactory('myCache');

var data = cache.get(someKey);

if (!data) {
   $http.get(url).success(function(result) {
      data = result;
      cache.put(someKey, data);
   });
}

47
Soru: Önbelleğe alınmış verileri $ cacheFactory'e kaydetmenin anlamı nedir? Neden yalnızca Hizmet'teki yerel bir nesneye kaydetmiyoruz? Bunun iyi bir nedeni var mı?
Spock

7
Şuna bir bak. LocalStorage desteği, zaman aşımı desteği, her türlü güzellik de dahil olmak üzere birçok özelleştirilebilirlik sunar http://jmdobry.github.io/angular-cache/
Erik Donohoo

4
Özellikle durum kodu 304'ü merak ediyorum - tarayıcı önbelleği önbelleği etkinleştirmeden çalışıyor mu: true? Değilse, cache: true çalışmasını sağlar mı? Önbellek kalıcı mı yoksa sadece RAM'de mi ve sayfa kapatıldığında yüksüz mü?
sasha.sochka

3
Manuel olarak uygulamadan bu önbellekte bir zaman sınırı belirtmenin herhangi bir yolu var mı?
Mark

11
@Spock, $ cacheFactory, birden fazla denetleyici ve açısal bileşende kullanılabilen bir hizmettir. Tüm $ http'lerinizi, her biri için farklı hizmet nesnelerine sahip olmak yerine tek bir hizmet nesnesine önbelleğe almak için genel bir api hizmeti olarak kullanılabilir.
Nirav Gandhi

48

Şimdi daha kolay bir yol olduğunu düşünüyorum. Bu, tüm $ http istekleri için temel önbellekleme sağlar ($ kaynak devralır):

 var app = angular.module('myApp',[])
      .config(['$httpProvider', function ($httpProvider) {
            // enable http caching
           $httpProvider.defaults.cache = true;
      }])

46
Her http isteğini önbelleğe almak istemezsiniz. Durumun ne zaman olacağını görmüyorum?
Spock

1
Her uygulama / modül farklı, değil mi ?!
rodrigo-silveira

13
İsteklerin çoğunu önbelleğe almak istiyorsanız, varsayılanı true olarak ayarlamak kullanışlıdır.
Adrian Lynch

12

Mevcut kararlı sürümde (1.0.6) bunu yapmanın daha kolay bir yolu çok daha az kod gerektirir.

Modülünüzü kurduktan sonra bir fabrika ekleyin:

var app = angular.module('myApp', []);
// Configure routes and controllers and views associated with them.
app.config(function ($routeProvider) {
    // route setups
});
app.factory('MyCache', function ($cacheFactory) {
    return $cacheFactory('myCache');
});

Şimdi bunu kontrolörünüze aktarabilirsiniz:

app.controller('MyController', function ($scope, $http, MyCache) {
    $http.get('fileInThisCase.json', { cache: MyCache }).success(function (data) {
        // stuff with results
    });
});

Bir dezavantajı, anahtar adlarının da otomatik olarak ayarlanmasıdır, bu da onları temizlemeyi zorlaştırabilir. Umarım anahtar isimleri almak için bir şekilde eklerler.


7

$ Http yerleşik önbelleğe alma, ancak daha fazla kontrol istiyorsanız kütüphane açısal önbellek göz atın . Yaşam süresi, periyodik temizleme ve önbelleği localStorage'a devam ettirme seçeneği ile $ http önbelleğini sorunsuz bir şekilde artırmak için kullanabilirsiniz.

FWIW, önbelleğinizi yalnızca varsayılan JSON dizeleri yerine POJO olarak etkileşime girebileceğiniz daha dinamik bir veri deposu haline getirmek için araçlar ve desenler de sağlar. Bu seçeneğin faydası hakkında henüz yorum yapılamıyor.

(Daha sonra, bununla ilgili olarak, ilgili kütüphane açısal verileri , $ resource ve / veya Restangular için bir değişikliktir ve açısal önbelleğe bağlıdır.)


3
Lütfen angular-dataartık kullanımdan kaldırıldığını unutmayın . En son js-data-angular js-data.io/v1.8.0/docs/js-data-angular
demisx

Açısal önbellek kitaplığı, Angular'ın $ cacheFactory içine yerleştirilmiş olması gereken özelliklere sahiptir. Yerleşik çözüm, belirli önbelleklerin süresinin dolmasına ilişkin sınırlamaları göz önüne alındığında neredeyse işe yaramaz gibi görünüyor. Açısal önbellek fabrikası da uygulaması en kolay 3. taraf kütüphanelerinden biriydi.
Darryl

5

AngularJS fabrikaları tekil olduğundan , http isteğinin sonucunu saklayabilir ve bir dahaki sefere servisinize enjekte edildiğinde geri alabilirsiniz.

angular.module('myApp', ['ngResource']).factory('myService',
  function($resource) {
    var cache = false;
    return {
      query: function() {
        if(!cache) {
          cache = $resource('http://example.com/api').query();
        }
        return cache;
      }
    };
  }
);

Nasıl GET başarısız olup olmadığını kontrol etmek için bir sorum var ve bu durumda $ resource ... query ()
robert

@robert .then yönteminin ikinci bağımsız değişkenini veya daha iyisini kontrol edebilirsiniz .catch geri aramasını kullanın. Örneğin $ http .get (url) .then (successCallback, failCallback) veya $ http .get (url) .then (successCallback, failCallback) .catch (errorCallback) failCallback'te kötü bir şey olsa bile hata geri çağrısı yürütülür , başarısız geri aramayı hiç önlemek ve .then (success) .catch (manageRequestFail) kullanmak daha yaygındır. Bu fikri kavramaya yardımcı olur umuyoruz, açısal $ http belgelerinde daha fazla bilgi.
Faito

2
angularBlogServices.factory('BlogPost', ['$resource',
    function($resource) {
        return $resource("./Post/:id", {}, {
            get:    {method: 'GET',    cache: true,  isArray: false},
            save:   {method: 'POST',   cache: false, isArray: false},
            update: {method: 'PUT',    cache: false, isArray: false},
            delete: {method: 'DELETE', cache: false, isArray: false}
        });
    }]);

önbelleği true olarak ayarlayın.


Bu, diğer herhangi bir web uygulaması gibi tarayıcının kendisini içeren istemci uygulaması kadar güvenli olacaktır.
bhantol

-1

Açısal 8'de bunu yapabiliriz:

import { Injectable } from '@angular/core';
import { YourModel} from '../models/<yourModel>.model';
import { UserService } from './user.service';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})

export class GlobalDataService {

  private me: <YourModel>;

  private meObservable: Observable<User>;

  constructor(private yourModalService: <yourModalService>, private http: HttpClient) {

  }

  ngOnInit() {

  }


  getYourModel(): Observable<YourModel> {

    if (this.me) {
      return of(this.me);
    } else if (this.meObservable) {
      return this.meObservable;
    }
    else {
      this.meObservable = this.yourModalService.getCall<yourModel>() // Your http call
      .pipe(
        map(data => {
          this.me = data;
          return data;
        })
      );
      return this.meObservable;
    }
  }
}

Buna şöyle diyebilirsiniz:

this.globalDataService.getYourModel().subscribe(yourModel => {


});

Yukarıdaki kod, uzak API'nin sonucunu ilk çağrıda önbelleğe alacaktır, böylece bu yönteme yönelik başka istekler için kullanılabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.