0

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

我需要在我的 sw-precache 配置中添加一些东西,以便让它按照角度来处理 html 文件的检索吗?

4

2 回答 2

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 文件的 service worker 缓存表示包含公共路径,在我的例子中:'/App/core/directives/location.html'。

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

然后我可以使用 match 方法找到匹配的 service worker 缓存内容,读取二进制流并转换为 HTML,然后告诉 $templateCache 用 service worker 缓存值替换它。

因此,为了完整性(您可以创建一个通用服务来替换基于 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,但是,有点晦涩,认为它对每个指令都更干净

于 2017-07-05T15:15:56.993 回答
1

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

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

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

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

于 2017-07-12T14:54:08.177 回答