AngularJS deshabilita el almacenamiento parcial en caché en la máquina de desarrollo


Tengo problemas con el almacenamiento en caché de parciales en AngularJS.

En mi página HTML tengo:

<body>
 <div ng-view></div>
<body>

Donde se cargan mis parciales.

Cuando cambio el código HTML en mi parte, el navegador todavía carga datos antiguos.

¿Hay alguna solución alternativa?

Author: Chris Martin, 2013-02-06

13 answers

Para el desarrollo también puede desactivar la caché del navegador-En Chrome Dev Tools en la parte inferior derecha haga clic en el engranaje y marque la opción

Desactivar caché (mientras DevTools está abierto)

Actualización: En Firefox existe la misma opción en la Sección Debugger -> Settings -> Advanced (verificada para la Versión 33)

Actualización 2: Aunque esta opción aparece en Firefox algunos informan que no funciona. Sugiero usar firebug y seguir la respuesta de hadaytullah.

 200
Author: LukeSolar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-27 12:07:10

Basándose un poco en la respuesta de @Valentyn, aquí hay una forma de borrar siempre automáticamente la caché cada vez que cambia el contenido de ng-view:

myApp.run(function($rootScope, $templateCache) {
   $rootScope.$on('$viewContentLoaded', function() {
      $templateCache.removeAll();
   });
});
 111
Author: Mark Rajcok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-06 04:06:12

Como se mencionó en las otras respuestas, aquí y aquí , la caché se puede borrar usando:

$templateCache.removeAll();

Sin embargo, como sugiere gatoatigrado en el comentario , esto solo parece funcionar si la plantilla html se sirvió sin encabezados de caché.

Así que esto funciona para mí:

En angular:

app.run(['$templateCache', function ( $templateCache ) {
    $templateCache.removeAll(); }]);

Es posible que esté agregando encabezados de caché de varias maneras, pero aquí hay un par de soluciones que funcionan para mí.

Si se usa IIS, añade esto a tu web.config:

<location path="scripts/app/views">
  <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="DisableCache" />
    </staticContent>
  </system.webServer>
</location>

Si usa Nginx, puede agregar esto a su configuración:

location ^~ /scripts/app/views/ {
    expires -1;   
}

Editar

Me acabo de dar cuenta de que la pregunta menciona dev máquina, pero espero que esto todavía puede ayudar a alguien...

 37
Author: Chris Foster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:16

Si usted está hablando de caché que se utiliza para el almacenamiento en caché de plantillas sin recargar toda la página, entonces usted puede vaciarlo por algo como:

.controller('mainCtrl', function($scope, $templateCache) {
  $scope.clearCache = function() { 
    $templateCache.removeAll();
  }
});

Y en el marcado:

<button ng-click='clearCache()'>Clear cache</button>

Y pulse este botón para borrar la caché.

 31
Author: Valentyn Shybanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-05 23:57:03

Solución Para Firefox (33.1.1) usando Firebug (22.0.6)

  1. Herramientas > Herramientas web > Firebug > Abrir Firebug.
  2. En las vistas Firebug ve a la vista "Net".
  3. Aparecerá un símbolo de menú desplegable junto a "Net" (título de la vista).
  4. Seleccione "Desactivar caché del navegador" en el menú desplegable.
 23
Author: hadaytullah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-22 23:27:08

Este fragmento me ayudó a deshacerme del almacenamiento en caché de plantillas

app.run(function($rootScope, $templateCache) {
    $rootScope.$on('$routeChangeStart', function(event, next, current) {
        if (typeof(current) !== 'undefined'){
            $templateCache.remove(current.templateUrl);
        }
    });
});

Los detalles del siguiente fragmento se pueden encontrar en este enlace: http://oncodesign.io/2014/02/19/safely-prevent-template-caching-in-angularjs /

 19
Author: Code Prank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-14 15:24:13

Estoy publicando esto solo para cubrir todas las posibilidades, ya que ninguna de las otras soluciones funcionó para mí (arrojaron errores debido a dependencias de plantillas angular-bootstrap, entre otros).

Mientras está desarrollando / depurando una plantilla específica, puede asegurarse de que siempre se actualice al incluir una marca de tiempo en la ruta, como esta:

       $modal.open({
          // TODO: Only while dev/debug. Remove later.
          templateUrl: 'core/admin/organizations/modal-selector/modal-selector.html?nd=' + Date.now(),
          controller : function ($scope, $modalInstance) {
            $scope.ok = function () {
              $modalInstance.close();
            };
          }
        });

Tenga en cuenta el ?nd=' + Date.now() final en la variable templateUrl.

 16
Author: diosney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-28 16:31:47

Como otros han dicho, derrotar el almacenamiento en caché completamente para fines de desarrollo se puede hacer fácilmente sin cambiar el código: use una configuración del navegador o un complemento. Fuera de dev, para derrotar el almacenamiento en caché de plantillas Angular de plantillas basadas en rutas, elimine la URL de la plantilla de la caché durante rout routeChangeStart (o stat stateChangeStart, para el enrutador de interfaz de usuario) como mostró Shayan. Sin embargo, eso NO afecta el almacenamiento en caché de las plantillas cargadas por ng-include, porque esas plantillas no se cargan a través del enrutador.

I quería poder corregir cualquier plantilla, incluidas las cargadas por ng-include, en producción y que los usuarios recibieran la revisión en su navegador rápidamente, sin tener que recargar toda la página. Tampoco me preocupa derrotar el almacenamiento en caché HTTP para las plantillas. La solución es interceptar cada solicitud HTTP que hace la aplicación, ignorar las que no son para mi aplicación .plantillas html, luego agrega un parámetro a la URL de la plantilla que cambia cada minuto. Tenga en cuenta que la comprobación de ruta es específica para la ruta de las plantillas de tu app. Para obtener un intervalo diferente, cambie las matemáticas para el parámetro o elimine el % por completo para no almacenar en caché.

// this defeats Angular's $templateCache on a 1-minute interval
// as a side-effect it also defeats HTTP (browser) caching
angular.module('myApp').config(function($httpProvider, ...) {
    $httpProvider.interceptors.push(function() {
        return {
            'request': function(config) {
                config.url = getTimeVersionedUrl(config.url);
                return config;
            }
        };
    });

    function getTimeVersionedUrl(url) {
        // only do for html templates of this app
        // NOTE: the path to test for is app dependent!
        if (!url || url.indexOf('a/app/') < 0 || url.indexOf('.html') < 0) return url;
        // create a URL param that changes every minute
        // and add it intelligently to the template's previous url
        var param = 'v=' + ~~(Date.now() / 60000) % 10000; // 4 unique digits every minute
        if (url.indexOf('?') > 0) {
            if (url.indexOf('v=') > 0) return url.replace(/v=[0-9](4)/, param);
            return url + '&' + param;
        }
        return url + '?' + param;
    }
 11
Author: bradw2k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-15 19:25:23

Si está utilizando UI router, puede usar un decorador y actualizar el servicio templ templateFactory y agregar un parámetro de cadena de consulta a templateUrl, y el navegador siempre cargará la nueva plantilla desde el servidor.

function configureTemplateFactory($provide) {
    // Set a suffix outside the decorator function 
    var cacheBust = Date.now().toString();

    function templateFactoryDecorator($delegate) {
        var fromUrl = angular.bind($delegate, $delegate.fromUrl);
        $delegate.fromUrl = function (url, params) {
            if (url !== null && angular.isDefined(url) && angular.isString(url)) {
                url += (url.indexOf("?") === -1 ? "?" : "&");
                url += "v=" + cacheBust;
            }

            return fromUrl(url, params);
        };

        return $delegate;
    }

    $provide.decorator('$templateFactory', ['$delegate', templateFactoryDecorator]);
}

app.config(['$provide', configureTemplateFactory]);

Estoy seguro de que puede lograr el mismo resultado decorando el método "when" en rout routeProvider.

 7
Author: Aman Mahajan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-14 05:26:21

Descubrí que el método HTTP interceptor funciona bastante bien, y permite flexibilidad y control adicionales. Además, puede cache-bust para cada versión de producción mediante el uso de un hash de liberación como la variable buster.

Así es como se ve el método dev cachebusting usando Date.

app.factory('cachebustInjector', function(conf) {   
    var cachebustInjector = {
        request: function(config) {    
            // new timestamp will be appended to each new partial .html request to prevent caching in a dev environment               
            var buster = new Date().getTime();

            if (config.url.indexOf('static/angular_templates') > -1) {
                config.url += ['?v=', buster].join('');
            }
            return config;
        }
    };
    return cachebustInjector;
});

app.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push('cachebustInjector');
}]);
 3
Author: cpreid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-24 16:55:36

Aquí hay otra opción en Chrome.

Pulsa F12 para abrir las herramientas de desarrollo. Entonces Recursos > Almacenamiento en Caché > Actualizar Cachés .

introduzca la descripción de la imagen aquí

Me gusta esta opción porque no tengo que desactivar la caché como en otras respuestas.

 1
Author: Jess,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-28 13:52:04

No hay solución para evitar el almacenamiento en caché del navegador/proxy, ya que no puede tener el control sobre él.

La otra forma de forzar contenido fresco a sus usuarios es cambiar el nombre del archivo HTML! Exactamente como https://www.npmjs.com/package/grunt-filerev hace para los activos.

 0
Author: Thomas Decaux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-03 15:11:26

Actualizar el documento cada 30 segundos:

<head>
  <meta http-equiv="refresh" content="30">
</head>

W3schools HTML http-equiv Attribute

 -3
Author: Eran Or,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-15 11:32:35