Lưu trữ phản hồi dịch vụ 'Nhận' HTTP trong AngularJS?


211

Tôi muốn có thể tạo một dịch vụ AngularJS tùy chỉnh để thực hiện yêu cầu 'Nhận' HTTP khi đối tượng dữ liệu của nó trống và đưa đối tượng dữ liệu thành công.

Lần tiếp theo cuộc gọi được thực hiện cho dịch vụ này, tôi muốn bỏ qua chi phí thực hiện lại yêu cầu HTTP và thay vào đó trả về đối tượng dữ liệu được lưu trong bộ nhớ cache.

Điều này có thể không?

Câu trả lời:


315

$ Http của Angular có bộ đệm được tích hợp sẵn . Theo các tài liệu:

bộ đệm - {boolean | Object} - Một giá trị hoặc đối tượng boolean được tạo bằng $ cacheFactory để bật hoặc tắt bộ đệm ẩn của phản hồi HTTP. Xem $ http Bộ đệm để biết thêm thông tin .

Giá trị Boolean

Vì vậy, bạn có thể đặt cachethành đúng trong các tùy chọn của nó:

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

hoặc, nếu bạn thích loại cấu hình của cuộc gọi:

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

Đối tượng bộ nhớ cache

Bạn cũng có thể sử dụng bộ đệm cache:

var cache = $cacheFactory('myCache');

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

Bạn có thể tự thực hiện bằng $ cacheFactory (đặc biệt là khi sử dụng $ resource):

var cache = $cacheFactory('myCache');

var data = cache.get(someKey);

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

47
Câu hỏi: điểm lưu dữ liệu được lưu trong bộ nhớ cache vào $ cacheFactory .. tại sao không lưu dữ liệu vào đối tượng cục bộ trong Dịch vụ? Bất kỳ lý do tốt?
Spock

7
Kiểm tra này. Nó cung cấp cho bạn rất nhiều tùy chỉnh bao gồm hỗ trợ LocalStorage, hỗ trợ thời gian chờ, tất cả các loại quà tặng http://jmdobry.github.io/angular-cache/
Erik Donohoo

4
Tôi đặc biệt tò mò về mã trạng thái 304 - bộ đệm của trình duyệt có hoạt động mà không bật bộ đệm: đúng không? Nếu không, cache: true có làm cho nó hoạt động không? Là bộ nhớ đệm vĩnh viễn hoặc nó chỉ trong RAM và không được tải khi đóng trang?
sasha.sochka

3
Bất kỳ cách nào để xác định giới hạn thời gian trên bộ đệm này mà không thực hiện thủ công?
Đánh dấu

11
@Spock, $ cacheFactory chính nó là một dịch vụ có thể được sử dụng trên nhiều bộ điều khiển và các thành phần góc. Nó có thể được sử dụng như một dịch vụ api chung để lưu trữ tất cả $ http của bạn vào một obj dịch vụ thay vì có các đối tượng dịch vụ khác nhau cho mỗi một trong số chúng.
Nirav Gandhi

48

Tôi nghĩ bây giờ có một cách dễ dàng hơn. Điều này cho phép bộ nhớ đệm cơ bản cho tất cả các yêu cầu $ http (mà $ resource kế thừa):

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

46
Bạn hầu như không muốn lưu trữ mọi yêu cầu http. Tôi không thấy khi nào nó sẽ xảy ra?
Spock

1
Mỗi ứng dụng / mô-đun là khác nhau, không?!
Rodrigo-silveira

13
Nếu bạn muốn lưu trữ phần lớn các yêu cầu thì đặt mặc định thành true là tiện dụng.
Adrian Lynch

12

Một cách dễ dàng hơn để làm điều này trong phiên bản ổn định hiện tại (1.0.6) đòi hỏi ít mã hơn.

Sau khi thiết lập mô-đun của bạn, thêm một nhà máy:

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');
});

Bây giờ bạn có thể chuyển cái này vào bộ điều khiển của bạn:

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

Một nhược điểm là các tên chính cũng được thiết lập tự động, điều này có thể khiến việc xóa chúng trở nên khó khăn. Hy vọng rằng họ sẽ thêm một số cách để có được tên chính.


7

Kiểm tra bộ đệm góc thư viện nếu bạn thích bộ nhớ đệm tích hợp của $ http nhưng muốn kiểm soát nhiều hơn. Bạn có thể sử dụng nó để tăng liên tục bộ đệm $ http với thời gian thực hiện, thanh lọc định kỳ và tùy chọn duy trì bộ đệm cho localStorage để nó có sẵn trong các phiên.

FWIW, nó cũng cung cấp các công cụ và mẫu để biến bộ đệm của bạn thành một loại lưu trữ dữ liệu năng động hơn mà bạn có thể tương tác với tư cách là POJO, thay vì chỉ các chuỗi JSON mặc định. Chưa thể nhận xét về tiện ích của tùy chọn đó.

(Sau đó, trên hết, dữ liệu góc của thư viện có liên quan là loại thay thế cho $ resource và / hoặc Restangular, và phụ thuộc vào bộ đệm góc.)


3
Xin lưu ý rằng angular-datakhông được chấp nhận ngay bây giờ. Mới nhất là js-data-angular js-data.io/v1.8.0/docs/js-data-angular
demisx

Thư viện angular-cache có các tính năng nên được tích hợp vào $ cacheFactory của Angular. Giải pháp tích hợp dường như gần như vô dụng với những hạn chế trong việc có thể hết hạn lưu trữ cụ thể. Nhà máy bộ nhớ cache góc là một trong những thư viện bên thứ 3 dễ thực hiện nhất.
Darryl

5

Vì các nhà máy của AngularJS là các singletons , bạn chỉ cần lưu trữ kết quả của yêu cầu http và truy xuất nó vào lần tới khi dịch vụ của bạn được đưa vào một cái gì đó.

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

Tôi có một câu hỏi làm thế nào để kiểm tra xem GET có thất bại không và trong trường hợp đó không đưa vào bộ nhớ cache $ resource ... query ()
robert

@robert bạn có thể kiểm tra đối số thứ hai của phương thức .then hoặc tốt hơn nữa, sử dụng hàm gọi lại .catch. Ví dụ: $ http .get (url) .then (thành côngCallback, failCallback) hoặc $ http .get (url) .then (thành công, phản hồi, failCallback) .catch (errorCallback) Việc gọi lại lỗi sẽ được thực hiện ngay cả khi có lỗi xảy ra trong failCallback , mặc dù nó phổ biến hơn để tránh cuộc gọi lại thất bại ở tất cả và sử dụng .then (thành công) .catch (ManageRequestFail). Hy vọng rằng sẽ giúp nắm bắt ý tưởng, thêm thông tin trong tài liệu $ http góc cạnh.
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}
        });
    }]);

đặt bộ đệm thành đúng.


Điều này sẽ an toàn như ứng dụng khách với chính trình duyệt giống như bất kỳ ứng dụng web nào khác.
bhantol

-1

Trong Angular 8 chúng ta có thể làm như thế này:

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;
    }
  }
}

Bạn có thể gọi nó như thế này:

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


});

Đoạn mã trên sẽ lưu trữ kết quả của API từ xa trong lần gọi đầu tiên để có thể sử dụng nó cho các yêu cầu tiếp theo đối với phương thức đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.