วิธีรีเฟรช / ยกเลิกการแคชทรัพยากร $ ใน AngularJS


95

ฉันมีทรัพยากร User $ ง่ายๆที่ใช้การใช้งานแคช $ http เริ่มต้นดังนี้:

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

สิ่งนี้ใช้ได้ดีมากเช่นเซิร์ฟเวอร์ของฉันถูกเรียกเพียงครั้งเดียวในแอปพลิเคชันของฉันจากนั้นค่าจะดึงมาจากแคช

แต่ฉันต้องการรีเฟรชค่าจากเซิร์ฟเวอร์หลังจากการดำเนินการบางอย่าง มีวิธีง่ายๆในการทำเช่นนั้นหรือไม่?

ขอบคุณ.


1
ฉันใช้ไม่เสถียร (1.1.5 แต่ฉันคิดว่ามันมีตั้งแต่ 1.1.2) cache- {boolean|Cache}- ถ้าเป็นจริงแคช $ http เริ่มต้นจะถูกใช้เพื่อแคชคำขอ GET มิฉะนั้นหากอินสแตนซ์แคชที่สร้างด้วย
Alexandre Bulté

1
ฉันมีปัญหาที่คล้ายกัน แต่เมื่อทำการทดสอบเท่านั้น ฉันจะทำลายสิ่งนี้ที่ระดับเบราว์เซอร์ได้อย่างไร
chovy

คำตอบ:


117

เก็บบูลีนและรับ$httpแคช:

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

จากนั้นคุณสามารถควบคุมได้เช่นเดียวกับแคชอื่น ๆ ที่สร้างด้วย$cacheFactoryอินสแตนซ์การใช้งานที่ให้ไว้ด้านล่าง:

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

52
สมบูรณ์แบบขอบคุณ! สิ่งที่ฉันกำลังมองหา สำหรับผู้ที่สงสัยคุณสามารถเรียก $ cacheFactory.get ('$ http') ลบ (คีย์) โดยคีย์เป็น URL สัมพัทธ์ของทรัพยากรของคุณ (เช่น / api / user / current / 51a9020d91799f1e9b8db12f)
Alexandre Bulté

2
อันที่จริงฉันพบว่าฉันต้องระบุ url แบบเต็มพร้อมกับพารามิเตอร์การค้นหาใด ๆ เมื่อเรียกลบ () ฉันขาดอะไรที่นี่?
shangxiao

3
ฉันมีพารามิเตอร์การสืบค้นแบบไดนามิก มีวิธีเข้าถึง url จาก$resourceโรงงานหรือไม่?
suzanshakya

1
ขณะนี้ใช้งานได้ อาจมีความซับซ้อนเกินความจำเป็น ทางออกที่ดีกว่าคือถ้าใช้: github.com/angular/angular.js/issues/9064
KFunk

5
สำหรับฉัน $ cacheFactory.get ('$ http') removeAll () ทำเคล็ดลับเพราะฉันต้องการล้างข้อมูลแคชทั้งหมด
S. Baggy

18

แทนที่จะใช้อาร์กิวเมนต์บูลีนในcacheคุณสมบัติของแต่ละรายการactionคุณสามารถส่งผ่านอินสแตนซ์แคชที่สร้างด้วย$ cacheFactoryซึ่งคุณสามารถควบคุมได้มากขึ้น (เช่นล้างแคช)

ตัวอย่างการใช้งาน:

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

ขอบคุณ. ฉันก็เห็นเช่นกัน แต่ฉันกำลังมองหาวิธี "มาตรฐาน" ที่จะทำก่อนที่จะไปตามเส้นทางนั้น ...
Alexandre Bulté

1
ดูเหมือนจะเป็นแนวทาง "มาตรฐาน" ที่สอดคล้องกับ "เชิงมุม" :)
ตัวแปร

1
คุณถูก. ฉันหมายถึงแนวทางที่มีแคชทรัพยากร $ มาตรฐาน
Alexandre Bulté

6

ฉันเจอหัวข้อนี้โดยมองหาสิ่งที่คล้ายกัน แต่พบว่า $ resource จะจัดการแคชให้คุณโดยอัตโนมัติดังนั้นจึงไม่จำเป็นต้องบังคับให้ล้างแคช

แนวคิดก็คือถ้าคุณมีทรัพยากรที่คุณสามารถสืบค้นได้การตอบกลับแบบสอบถามนั้นจะถูกแคช แต่ถ้าคุณบันทึกบางสิ่งสำหรับทรัพยากรเดียวกันนั้นข้อมูลที่แคชไว้ก่อนหน้านี้จะต้องไม่ถูกต้องดังนั้นจึงถูกล้างให้คุณ มันทำให้รู้สึกว่ามันจะทำงานในลักษณะนี้

นี่คือรหัสบางส่วนที่ฉันใช้เพื่อทำสิ่งนี้ (คุณสามารถเพิกเฉยต่อส่วนการสร้างโรงงานที่ดูแปลก ๆ และให้ความสนใจกับเนื้อหา "คลาส")

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

หากคุณเรียกใช้ฟังก์ชัน listPlayers หลายครั้งการโทรครั้งแรกจะส่งคำขอรับ http และการโทรที่ตามมาทั้งหมดจะถูกแคช หากคุณเรียก addPlayer โพสต์ http จะดำเนินการตามที่คาดไว้จากนั้นการโทรไปยัง listPlayers ครั้งถัดไปจะดำเนินการรับ http (ไม่แคช)

สิ่งนี้ช่วยให้คุณไม่ต้องทำงานในการจัดการแคช ($ http) ของผู้อื่นและพยายามติดตามว่า URL ใดถูกใช้สำหรับคำขอและกำลังล้างแคชในเวลาที่เหมาะสม

ฉันคิดว่าคุณธรรมของเรื่องนี้คือการทำงานกับห้องสมุดและทุกอย่างจะดี ... ยกเว้นข้อบกพร่องหรือคุณสมบัติที่ไม่สมบูรณ์ แต่ Angular ไม่มีสิ่งเหล่านี้)

ps ทั้งหมดนี้ทำงานบน AngularJS 1.2.0


2
ใช่ฉันเข้าใจและรับทราบว่าในสภาวะ "ปกติ" ทรัพยากร Angular จะรู้ว่าจะทำให้แคชเป็นโมฆะได้อย่างไรและเมื่อใดและทำงานได้อย่างสมบูรณ์ แต่กรณีการใช้งานของฉันแตกต่างกันเล็กน้อย: ฉันต้องการบังคับให้รีเฟรชเนื่องจาก Angular ไม่มีทางรู้ว่าจำเป็นต้องมีการรีเฟรช - วัตถุของผู้ใช้ที่ถูกแก้ไขนอกแอป Angular
Alexandre Bulté

3
ใครสามารถชี้ไปที่เอกสารนี้? ฉันเคยอ่านเกี่ยวกับสิ่งนี้มาก่อนใน Stack Overflow แต่ไม่พบการกล่าวถึงในเอกสารประกอบ ฉันได้ลองใช้เช่นกันในแอปของฉัน แต่อาจมีบางอย่างผิดพลาดระหว่างทาง ...
Sunil D.

1
ดูเหมือนว่าจะไม่ทำงานกับ $ delete สายถัดไปจะดึงจากแคชอีกครั้งและรายการที่ถูกลบจะปรากฏขึ้นอีกครั้ง มีใครยืนยันได้ไหม
Lukus

สิ่งนี้จะไม่ทำงาน ngResource DO NOT HANDLE cache invalidation ไปที่นี่เช่น: stackoverflow.com/questions/25117388/…
HugoPoi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.