2016-07-03 91 views
4

我使用angularjs並使用服務工作來接收推送通知。 但navigator.serviceWorker.controller爲空,直到頁面刷新,我不知道該怎麼做才能解決這個問題navigator.serviceWorker.controller爲空,直到頁面刷新

serviceworker的一些代碼:

self.addEventListener('push', pwServiceWorker.pushReceived); 
self.addEventListener('notificationclick', pwServiceWorker.notificationClicked); 

// refresh caches 
self.addEventListener('activate', function (event) 
{ 
    event.waitUntil(
     caches.keys().then(function (cacheNames) 
     { 
      return Promise.all(
       cacheNames.map(function (cacheName) 
       { 
        return caches.delete(cacheName); 
       }) 
      ); 
     }) 
    ); 
}); 

和serviceworker發送消息給客戶端當推接收:

self.clients.matchAll().then(function(all) { 
    console.log(all); 
    all.forEach(function(client) { 
     client.postMessage(data); 
    }); 
}); 
在mainController.js

給消息是這樣的:

if (!navigator.serviceWorker || !navigator.serviceWorker.register) { 
     console.log("This browser doesn't support service workers"); 
     return; 
    } 

    // Listen to messages from service workers. 
    navigator.serviceWorker.addEventListener('message', function(event) { 
     console.log("Got reply from service worker: " + event.data); 
    }); 

    // Are we being controlled? 
    if (navigator.serviceWorker.controller) { 
     // Yes, send our controller a message. 
     console.log("Sending 'hi' to controller"); 
     navigator.serviceWorker.controller.postMessage("hi"); 
    } else { 
     // No, register a service worker to control pages like us. 
     // Note that it won't control this instance of this page, it only takes effect 
     // for pages in its scope loaded *after* it's installed. 
     navigator.serviceWorker.register("service-worker.js") 
      .then(function(registration) { 
       console.log("Service worker registered, scope: " + registration.scope); 
       console.log("Refresh the page to talk to it."); 
       // If we want to, we might do `location.reload();` so that we'd be controlled by it 
      }) 
      .catch(function(error) { 
       console.log("Service worker registration failed: " + error.message); 
      }); 
    } 
+0

發佈一些代碼,否則沒有人可以幫助你。 – GillesC

+0

[由於控制器值爲空,無法向服務工作人員發送消息]的可能重複(http://stackoverflow.com/questions/37050383/unable-to-post-message-to-service-worker-because-controller-value -is-null) – Marco

回答

9

這是預期的行爲。接管所有打開的網頁控制,而無需等待刷新/重開,則必須將這些命令添加到您的服務人員:

self.addEventListener('install', function(event) { 
    event.waitUntil(self.skipWaiting()); // Activate worker immediately 
}); 

self.addEventListener('activate', function(event) { 
    event.waitUntil(self.clients.claim()); // Become available to all pages 
}); 

可以在skipWaiting()文檔和clients.claim()文檔閱讀更多有關他們。

+0

這些'event.waitUntil(...'函數除了緩存函數之外還有其他的功能(請參閱原始問題)還是替換它們?如果替換它們,它們何時被使用? – GreatBlakes

+0

[我發現這個snippet](https://serviceworke.rs/immediate-claim_service-worker_doc.html),它使用它們作爲回調,對我來說非常合適 – GreatBlakes

+1

我想要提出的另一個說明是,[shift + reload將繞過服務工作者](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#shift-reload),窗口將不受控制! – GreatBlakes