带服务工作者问题的角度模板缓存

时间:2017-06-25 03:41:25

标签: angularjs service-worker sw-precache

我有一个gulp设置,将我的所有html放在模板缓存中,以便更快地访问角度。我正在尝试使用sw-precache将一个服务工作者添加到我的项目中,以便可以脱机使用它。如果我连接到网络,一切正常。当我离线时,对html资源(位于模板缓存中)的请求失败,因为它似乎正在请求来自网络的路径。

我是否需要添加到我的sw-precache配置中,以便将其推迟到处理html文件的检索?

2 个答案:

答案 0 :(得分:2)

好的,这就是我解决这个问题的方法。我正在使用带有sw-precache的Angular JS 1.6.4。

我通过服务工作者拥有CacheStorage,所以使用服务工作者我知道我希望设备支持某些功能,在我的情况下,我们知道我们的用户将拥有带有Chrome的Android平板电脑并且支持是有效的。

我正在开发具有离线功能的渐进式网络应用。

所以,理论......我的指令有templateUrls。

使用这篇文章:https://thinkster.io/templatecache-tutorial

我基本上有我的指令代码:

angular.module('app').directive('location',
['$timeout', 'notify.service', 'user.settings.service', 'log.service',
    function ($timeout, notify, userSettings, log) {
        return {
            restrict: 'EA',
            ... controller etc.., 
            templateUrl: '/App/core/directives/location.html'
        }
    }
]);

现在,当这个应用程序离线时,内容的缓存实例没有踢它 - 很烦人。

所以,经过多次拖延,我陷入了困境。

我的解决方法是,保持templateUrl不变,但通过$ templateCache服务覆盖内容。

要执行此操作,请在指令后附加RUN函数(为清楚起见)。我们知道我们的Url文件的服务工作者缓存表示包含公共路径,在我的例子中:' /App/core/directives/location.html'。

因此,在浏览器中使用新技术,window.caches让我可以访问服务工作者使用的CacheStorage,然后我可以使用可用的API:https://developer.mozilla.org/en-US/docs/Web/API/Cache

然后我可以使用match方法查找匹配的服务工作者缓存内容,读取该二进制流并转换为HTML,然后告诉$ templateCache将其替换为服务工作者缓存值。

因此,为了完整性(您可以创建一个公共服务来替换基于templateUrl的缓存值 - 我将为每个指令执行此操作)

(function () {

    'use strict';

    var templateUrl = '/App/core/directives/location.html';

    // <location on-location='someFunc'></location>
    // provides a form/control to find a location either by GEO location or manual city search
    angular.module('app')
            .run(['$templateCache', function ($templateCache) {
                var cache = window.caches;

                cache.match(templateUrl, { ignoreSearch: true }).then(function (response) {

                    if (response) {
                        response.body.getReader().read().then(function (cachedResponse) {
                            // convert the Uint8Array value to HTML string
                            var content = new TextDecoder('utf-8').decode(cachedResponse.value);
                            $templateCache.put(templateUrl, content);
                            //console.log($templateCache.get(templateUrl)); // debug
                        });
                    }
                });


            }])
    .directive('location',
    ['$timeout', 'notify.service', 'user.settings.service', 'log.service',
        function ($timeout, notify, userSettings, log) {
            return {
                restrict: 'EA',
                ... controller, scope etc...
                templateUrl: templateUrl
            }
        }
    ]);  
})();

退出...... RUN流程是同步的,所以最初他们必须首先在线访问网站......但这就是服务工作者需要如何工作,以便在培训中处理:)

我希望有更好的选择,但暂时就是我所拥有的解决方案,我将创建一个模板服务,根据每个指令将具有的var templateUrl替换$ templateCache值,因此代码变得更清晰在每个直接的....我考虑有一个全球模板和文件arr,但是,只是有点模糊,认为它的每个指令更清洁

答案 1 :(得分:1)

我的原始解决方案不是100%

要解决此问题,请使用sw-precache和sw-toolbox

使用gulp配置,您可以设置sw-precache来缓存内容并使用sw-toolbox扩展它以使用基于路由配置的缓存响应

请参阅:https://developers.google.com/web/ilt/pwa/using-sw-precache-and-sw-toolbox