Cách làm mới / vô hiệu hóa bộ nhớ cache của $ resource trong AngularJS


94

Tôi có một tài nguyên Người dùng $ đơn giản sử dụng triển khai bộ đệm $ http mặc định như sau:

factory('User', function($resource){
    return $resource(endpoint + '/user/current/:projectId', {},
        {get: 
            {
                cache: true,
                method: 'GET'
            }
        }
    );
})

Điều này hoạt động rất tốt, tức là máy chủ của tôi chỉ được gọi một lần trong ứng dụng của tôi, sau đó giá trị được tìm nạp từ bộ nhớ cache.

Nhưng tôi cần làm mới giá trị từ máy chủ sau một thao tác nhất định. Có một cách dễ dàng để làm điều đó?

Cảm ơn.


1
Tôi đang sử dụng không ổn định (1.1.5 nhưng tôi nghĩ nó ở đó kể từ 1.1.2) cache- {boolean|Cache}- Nếu đúng, bộ đệm $ http mặc định sẽ được sử dụng để lưu vào bộ đệm yêu cầu GET, ngược lại nếu một phiên bản bộ đệm được xây dựng bằng
Alexandre Bulté

1
tôi đang gặp vấn đề tương tự nhưng chỉ khi thử nghiệm. làm thế nào để phá vỡ thứ này ở cấp trình duyệt?
chovy

Câu trả lời:


116

Giữ boolean và lấy $httpbộ nhớ cache:

var $httpDefaultCache = $cacheFactory.get('$http');

Sau đó, bạn có thể kiểm soát nó giống như bất kỳ bộ đệm nào khác được tạo bằng $cacheFactory, một phiên bản sử dụng được cung cấp bên dưới:

$httpDefaultCache.remove(key);
// Where key is the relative URL of your resource (eg: /api/user/current/51a9020d91799f1e9b8db12f)

52
Hoàn hảo, cảm ơn bạn! Chính xác những gì tôi đang tìm kiếm. Đối với những người thắc mắc, bạn có thể gọi $ cacheFactory.get ('$ http'). Remove (key), với khóa là URL tương đối của tài nguyên của bạn (ví dụ: / api / user / current / 51a9020d91799f1e9b8db12f).
Alexandre Bulté

2
Trên thực tế, tôi thấy rằng tôi cần chỉ định url đầy đủ cùng với bất kỳ tham số truy vấn nào khi gọi remove (). Am i thiếu cái gì ở đây?
shangxiao

3
Tôi có các tham số truy vấn động. Có cách nào để truy cập url từ $resourcenhà máy không?
suzanshakya

1
Trong khi điều này hoạt động. Nó có thể phức tạp hơn mức cần thiết. Giải pháp tốt hơn sẽ là nếu điều này được triển khai: github.com/angular/angular.js/issues/9064
KFunk

5
Đối với tôi, $ cacheFactory.get ('$ http'). RemoveAll () đã thực hiện một mẹo nhỏ, vì tôi cần xóa tất cả dữ liệu được lưu trong bộ nhớ cache.
S. Baggy

18

Thay vì sử dụng một đối số boolean trong thuộc cachetính của mỗi thuộc tính, actionbạn có thể truyền vào một cá thể bộ đệm được tạo bằng $ cacheFactory mà bạn có thể kiểm soát nhiều hơn (tức là xóa bộ nhớ cache).

Ví dụ sử dụng:

app.factory('Todos', function($resource, $cacheFactory) {
    var cache = $cacheFactory('todo');
    return $resource(apiBaseUrl + '/todos/:id', { id: '@id' }, {
        'get': { method: 'GET', cache: cache  },
        'query': { method: 'GET', cache: cache, isArray: true }
    });
});

Cảm ơn. Tôi thấy điều đó quá, nhưng tôi đã tìm kiếm một cách "chuẩn" để làm điều đó trước khi đi xuống con đường đó ...
Alexandre Bulté

1
có vẻ như là một cách tiếp cận rất "tiêu chuẩn" phù hợp với "cách góc cạnh" :)
Biến thể.

1
Bạn đúng. Ý tôi là một cách tiếp cận với bộ nhớ cache $ tài nguyên tiêu chuẩn.
Alexandre Bulté

6

Tôi đã xem qua chuỗi này đang tìm kiếm thứ gì đó tương tự, nhưng nhận thấy rằng $ resource sẽ tự động quản lý bộ nhớ cache cho bạn, vì vậy không cần phải buộc xóa bộ nhớ cache.

Ý tưởng là nếu bạn có một tài nguyên mà bạn có thể truy vấn, thì phản hồi truy vấn đó sẽ được lưu vào bộ nhớ cache, nhưng nếu bạn lưu thứ gì đó cho cùng một tài nguyên đó, thì dữ liệu đã lưu trong bộ nhớ cache trước đó phải không hợp lệ, vì vậy nó sẽ bị xóa cho bạn. Nó có ý nghĩa rằng nó sẽ hoạt động theo cách này.

Đây là một số mã tôi sử dụng để thực hiện việc này (bạn có thể bỏ qua phần tạo nhà máy có thể trông kỳ quặc và chú ý đến phần thân "lớp").

'use strict';

sampleApp.players.$ng.factory('sampleApp.players.PlayerService', [
    '$log',
    '$resource',
    sampleApp.players.PlayerService = function ($log, $resource) {
        var service = {};

        $log.info('Creating player resource.');
        var Player = $resource('/api/players', {}, {query: {
            isArray: true,
            cache: true,
            method: 'GET'
        }});

        service.addPlayer = function(playerName) {
            $log.info('Saving a new player.');
            return new Player({name: playerName}).$save();
        };

        service.listPlayers = function () {
            $log.info('Fetching players.');
            return Player.query();
        };

        return service;
    }]);

Nếu bạn gọi hàm listPlayers nhiều lần, cuộc gọi đầu tiên sẽ tạo ra một yêu cầu nhận http và tất cả các cuộc gọi tiếp theo sẽ được lưu vào bộ nhớ đệm. Tuy nhiên, nếu bạn gọi addPlayer, một bài đăng http sẽ được thực hiện như mong đợi, và sau đó lần gọi tiếp theo đến listPlayers sẽ thực hiện một http get (không được lưu trong bộ nhớ đệm).

Điều này giúp bạn không phải quản lý bộ nhớ cache ($ http) của người khác và cố gắng theo dõi url nào đang được sử dụng cho các yêu cầu và đang xóa bộ nhớ cache vào đúng thời điểm.

Tôi cho rằng đạo lý của câu chuyện ở đây là làm việc với thư viện và tất cả sẽ ổn ... ngoại trừ bất kỳ lỗi nào hoặc các tính năng chưa hoàn thiện, nhưng Angular không có bất kỳ điều nào trong số đó;)

ps Đây là tất cả chạy trên AngularJS 1.2.0.


2
Có, tôi hiểu và thừa nhận rằng trong điều kiện "bình thường", tài nguyên Angular biết cách thức và thời điểm làm mất hiệu lực bộ nhớ cache, và nó hoạt động hoàn hảo. Nhưng trường hợp sử dụng của tôi hơi khác: Tôi muốn buộc làm mới vì Angular không có cách nào biết rằng cần phải làm mới - đối tượng người dùng đang được sửa đổi bên ngoài ứng dụng Angular.
Alexandre Bulté

3
Bất cứ ai có thể chỉ nơi điều này được tài liệu? Tôi đã đọc về điều này trước đây trên Stack Overflow, nhưng không thể tìm thấy bất kỳ đề cập nào về nó trong tài liệu. Tôi đã thử nó cũng như trong ứng dụng của tôi, nhưng có lẽ có cái gì sai done trên đường đi ...
Sunil D.

1
Tuy nhiên, nó không hoạt động với $ delete. Cuộc gọi tiếp theo sẽ lại kéo từ bộ nhớ cache và mục đã xóa sẽ xuất hiện lại. Bất cứ ai có thể xác nhận?
Lukus

Sẽ không làm việc ngResource không xử lý bộ nhớ cache vô hiệu này đi đây ví dụ: stackoverflow.com/questions/25117388/...
HugoPoi
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.