ค้นหาเว็บไซต์

typescript - NullInjectorError: ไม่มีตัวจัดหา (provider) สำหรับ SwUpdate! SwUpdate ใช้งานไม่ได้ใน Angular 5


ตอนนี้ฉันรู้ว่ามีโพสต์เกี่ยวกับ 'ไม่มีผู้ให้บริการสำหรับบริการดังกล่าว' หลายล้านโพสต์ ฉันรู้ว่ามันต้องใส่ใน providers โปรดอ่านโพสต์ของฉันทั้งหมด

โดยพื้นฐานแล้วฉันกำลังพยายามใช้ SwUpdate เพื่อตรวจสอบว่ามีการอัปเดตหรือไม่ หากมี ให้รีเฟรชเบราว์เซอร์:

import { SwUpdate } from '@angular/service-worker';
...

export class ...

constructor(
    private _swUp: SwUpdate
){} 


ngOnInit() {
    this.checkForUpdate();
}

checkForUpdate() {
    if (this._swUp.isEnabled) {
       this._swUp.available
           .subscribe(() => {
               window.location.reload();
           });
    }
}

ตอนนี้ฉันได้ลงทะเบียน serviceworker ของฉันแล้ว:

import { ServiceWorkerModule } from '@angular/service-worker'; 
...

imports: [
    environment.production ? ServiceWorkerModule.register('ngsw-worker.js') : [],
]

ตอนนี้เมื่อฉันรันแอปของฉัน ฉันได้รับข้อผิดพลาดนี้:

NullInjectorError: No provider for SwUpdate!

ดังนั้นชัดเจนว่าฉันพยายามเพิ่มมันลงในอาร์เรย์ providers ในโมดูลคอมโพเนนต์ของฉัน:

import { ServiceWorkerModule, SwUpdate } from '@angular/service-worker'; 
...

imports: [
    environment.production ? ServiceWorkerModule.register('ngsw-worker.js') : [],
],
providers: [
    SwUpdate
]

ตอนนี้สิ่งนี้ควรจะทำงานได้ แต่ครั้งนี้เมื่อฉันเรียกใช้งานแอปพลิเคชัน ฉันได้รับข้อผิดพลาดดังต่อไปนี้:

NullInjectorError: No provider for NgswCommChannel!

ตอนนี้เมื่อฉันพยายามนำเข้า NgswCommChannel ฉันได้รับข้อผิดพลาดบอกว่ามันไม่มีอยู่ใน @angular/service-worker;

ฉันลองค้นหาใน Google แต่ไม่พบการอ้างอิงถึง NgswCommChanel เลยสักที่...

ดังนั้นคำถามของฉันคือฉันจะแก้ไขสิ่งนี้ได้อย่างไร หรือฉันสามารถใช้ SwUpdate ได้อย่างถูกต้องอย่างไร ??

จะซาบซึ้งกับความช่วยเหลือใด ๆ

แก้ไข

ฉันก็ได้ลองทำมันในแบบเดียวกัน EXACT ตามที่ทำในเอกสารอย่างเป็นทางการของ Angular และมันก็ยังให้ข้อผิดพลาดเดียวกันกับฉัน:

constructor(
    updates: SwUpdate
) {
    updates.available
        .subscribe(() => {
            updates.activateUpdate()
                .then(() => document.location.reload());
        });
}

แก้ไข 2 นี่คือสิ่งที่ฉันได้รับเมื่อฉันรัน ng -v

Angular CLI: 1.7.4
Node: 10.15.1
OS: win32 x64
Angular: 5.1.2
... animations, common, compiler, compiler-cli, core, forms
... http, platform-browser, platform-browser-dynamic
... platform-server, router

@angular/cli: 1.7.4
@angular/service-worker: 7.2.7
@angular-devkit/build-optimizer: 0.3.2
@angular-devkit/core: 0.3.2
@angular-devkit/schematics: 0.0.40
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.10.2
typescript: 2.4.2
webpack: 3.11.0

แก้ไข 3

จากการสอบสวนเพิ่มเติมดูเหมือนว่าคุณไม่สามารถใช้ SwUpdate เมื่อรันโปรเจกต์ของคุณในเครื่องได้ ฉันเห็นบทความ angular-pwa-pitfalls และวิธีแก้ของพวกเขาคือการติดตั้ง ng-toolkit แต่สิ่งนี้ก็เพียงแค่ทำให้คุณสามารถสร้างโปรเจกต์ของคุณแล้วรันเซิร์ฟเวอร์จำลอง ซึ่งก็ไม่มีประโยชน์เพราะฉันจะสูญเสียความสามารถในการพัฒนาในเครื่องโดยไม่ต้องสร้างโปรเจกต์ทุกครั้ง

แก้ไข 4

ฉันได้เปลี่ยนไฟล์ app.module.ts ของฉันเพื่อทำการลงทะเบียน service worker:

ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })

แต่ตอนนี้ฉันกำลังเจอข้อผิดพลาดชุดใหม่ทั้งหมด

คำแนะนำอื่น ๆ ก็ยินดีมาก

ขอบคุณ

คำตอบ #1

ปัญหาของคุณอยู่ใน app.module.ts

คุณจำเป็นต้องนำเข้า service worker ของคุณแบบนี้:

imports: [
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
],

โค้ดที่คุณมีมาก่อนหน้านี้จะรวมโมดูลเฉพาะเมื่อคุณอยู่ในโหมดโปรดักชัน ดังนั้นในระหว่างการพัฒนา มันจึงไม่ได้รวมโมดูลเลย

แก้ไข :

ภายใน app.component.ts ของฉัน ฉันมี:

constructor(private swUpdate: SwUpdate) { }

ngAfterViewInit() {
  if (this.swUpdate.isEnabled) {
    this.swUpdate.available
      .subscribe(() => {
        this.swUpdate
          .activateUpdate()
          .then(() => {
            window.location.reload();
          });
      });
  }
}

แก้ไข :

ตามความคิดเห็นของคุณ การอัปเดตเป็นเวอร์ชันล่าสุดของ Angular แก้ไขปัญหาของคุณได้ ดีใจที่พวกเขาทำให้การอัปเกรดง่ายขึ้นมากตอนนี้ :)

คำตอบ #2

สำหรับผู้ที่พบข้อผิดพลาดนี้เมื่อพยายามเขียนยูนิตเทสต์ วิธีแก้ไขคือการเพิ่ม ServiceWorkerModule ลงในอาเรย์ imports พร้อมกับตัวเลือก enable เป็น false เมื่อกำหนดค่า TestBed:

TestBed.configureTestingModule({
  declarations: [ MyComponent ],
  imports: [
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: false })
  ]
})
.compileComponents();

บทความที่เกี่ยวข้อง