workbox-webpack-plugin&有角度的.如何在Angular中收听broadcastUpdate事件 [英] workbox-webpack-plugin & Angular. How to listen to broadcastUpdate event in Angular

查看:73
本文介绍了workbox-webpack-plugin&有角度的.如何在Angular中收听broadcastUpdate事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的Angular应用程序中使用service-worker.它是使用webpack构建的.

I'm trying to use service-worker with my Angular Application. It is build using webpack.

我使用workbox-webpack-plugin.我想为我的GET API调用提供表单缓存,并在后台更新数据.

I use workbox-webpack-plugin. I want to serve my GET API calls form cache and in the background update the data.

为此,我将选项 runtimeCaching 与处理程序 staleWhileRevalidate (

FOr this, I use the option runtimeCaching with the handler staleWhileRevalidate (more details on GenerateSW plugin here)

这是我在webpack.config.js中拥有的配置:

This is the config I have in webpack.config.js:

  new GenerateSW({
    // importWorkboxFrom: 'local',
    clientsClaim: true,
    skipWaiting: true,
    navigateFallback: '/index.html',
    runtimeCaching: [
      {
        // Match any same-origin request that contains 'api'.
        urlPattern: /https:\/\/api.*/,
        handler: 'staleWhileRevalidate',
        options: {
          cacheName: 'api',
          broadcastUpdate: {
            channelName: 'api-updates',
          },
          // Add in any additional plugin logic you need.
          plugins: [],
        },
      }
    ]
  }),

根据本文档,我在缓存更新时应该能够接收到一个事件(我想向用户显示一些内容,以便他可以刷新数据).

According to this documentation, I should be able to receive an event when the cache is updated (I want to display something to the user so he can refresh the data).

用于接收数据的代码如下:

The code to receive the data look like this:

export class AppComponent implements OnInit {

  public ngOnInit() {
    console.log( 'AppComponent - ngOnInit' );

    const updatesChannel = new BroadcastChannel('api-updates');
    updatesChannel.addEventListener('message', async (event) => {
      console.log('Event received');
    });
  }
}

我将此代码放在我的Angular组件之一中,即使我确定缓存已更新,也从未被调用.

I put this code inside one of my Angular component, it never got called even if I'm sure that the cache was updated.

我认为这可能与Angular中更改检测的工作方式有关(

I think it might have something to do with how change detection works in Angular (like described in this question) but I'm not sure how to fix it.

有人能成功从Angular组件收听广播事件吗?

推荐答案

使用工作箱文档查找解决方案很困难.

Had difficulties finding a solution with workbox documentation.

在您启动应用时,您可以注册到工作盒服务工作人员,并在检测到更改并加载时覆盖 onupdatefound 更新UI:

On start of you app, you can register to workbox serviceworker and override onupdatefound update the UI when detecting a change and loading it:

if (process.env.NODE_ENV != "development" && "serviceWorker" in navigator) {
  window.addEventListener("load", () => {
    navigator.serviceWorker
      .register("/service-worker.js")
      .then(registration => {
        registration.onupdatefound = event => {
          console.log("An update has been detected. Workbox will now download the newest version, then send a notification.");
        };
      })
      .catch(registrationError => {
        console.log("SW registration failed: ", registrationError);
      });
  });
}

当工作箱检测到当前缓存版本与服务器上存储的版本之间的差异(作为哈希存储在 precache-manifest.d6104197c4431d9f111e4c4f0bdf858d.js )时,将触发此事件.

This is triggered when workbox detect difference between current cached version and the one stored on server (stored as a hash in precache-manifest.d6104197c4431d9f111e4c4f0bdf858d.js).

要检测接收到的文件并准备加载的实际更新,我无法按照文档中的说明选择选项 broadcastUpdate ,因此受其启发,我在webpack和我的应用之间实现了MessageChannel.

To detect the actual update with files received and ready to load, I couldn't make the option broadcastUpdate as described in documentation so inspired by it I implemented a MessageChannel between webpack and my app.

在Webpack中:

new WorkboxPlugin.GenerateSW({
      // these options encourage the ServiceWorkers to get in there fast
      // and not allow any straggling 'old' SWs to hang around
      clientsClaim: true,
      skipWaiting: true,
      include: [
        /\.html$/,
        /\.js$/,
        /\.jpg$/,
        /\.svg$/,
        /\.png$/,
        /\.json$/,
        /\.xml$/
      ],
      runtimeCaching: [
        {
          urlPattern: /./,
          handler: "StaleWhileRevalidate",
          options: {
            // Add in any additional plugin logic you need.
            plugins: [
              {
                cacheDidUpdate: event => {
                  clients.matchAll().then(clients => {
                    clients.forEach(client => {
                      var msg_chan = new MessageChannel();
                      client.postMessage("APP_UPDATE", [msg_chan.port2]);
                    });
                  });
                }
              }
            ]
          }
        }
      ]
    })

这将从我不知道该频道的位置发送一条消息.然后,我们可以在应用程序中的该频道上添加一个侦听器以触发用户界面.

This will send a message from I don't know where to a channel. We can then add a listenner on that channel in app to trigger ou UI.

在应用中:

if ("serviceWorker" in navigator) {
  navigator.serviceWorker.addEventListener("message", event => {
    if (event.data == "APP_UPDATE") {
      dispatch(AppActions.cacheDidUpdate());
    }
  });
}

这篇关于workbox-webpack-plugin&有角度的.如何在Angular中收听broadcastUpdate事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆