Angular PWA, как запросить сообщение для пользователей, чтобы они могли узнать и перезагрузить приложение после развертывания нового кода - PullRequest
0 голосов
/ 26 мая 2020

Я исследовал и знаю, что многие люди спрашивали об этой проблеме, но я все еще не могу решить возникшую у меня проблему. Поэтому я задам вопрос еще раз.

Я разрабатываю приложение, использующее Angular PWA. Я хочу, чтобы каждый раз после развертывания приложение отображало сообщение, и пользователь нажимал на него, чтобы перезагрузить приложение.

В настоящее время я использовал SwUpdate для проверки доступной новой версии, но он не запрашивает сообщение для me (я изменил заголовок в файле index. html и обновил код в некоторых других компонентах).

Я создал службу под названием PwaUpdateService, в этой службе я определил метод checkForUpdates (). После этого я вызываю этот метод в AppComponent.

Вот мой код:

import {SwUpdate} from '@angular/service-worker';
import {Injectable} from '@angular/core';
import {interval} from 'rxjs';

@Injectable()
export class PwaUpdateService {
  updateSubscription;

  constructor(public updates: SwUpdate) {
  }

  public checkForUpdates(): void {
    this.updateSubscription = this.updates.available.subscribe(event => this.promptUser());

    if (this.updates.isEnabled) {
      // Required to enable updates on Windows and ios.
      this.updates.activateUpdate().then();

      interval(60 * 60 * 1000).subscribe(() => {
        this.updates.checkForUpdate().then(() => {
          // console.log('checking for updates');
        });
      });

    }

    // Important: on Safari (ios) Heroku doesn't auto redirect links to their https which allows the installation of the pwa like usual
    // but it deactivates the swUpdate. So make sure to open your pwa on safari like so: https://example.com then (install/add to home)
  }

  promptUser(): void {
    this.updates.activateUpdate().then(() => {
      window.location.reload();
    });
  }
}

В AppComonent:

export class AppComponent {
  constructor(private screen: ScreenService,
              private sw: PwaUpdateService) {

    // check the service worker for updates
    this.sw.checkForUpdates();
  }
}

Это код, по которому я следовал руководству Angular, но мне не повезло.

Спасибо, что нашли время, чтобы посмотреть мои вопросы, надеюсь, вы поможете мне решить эту проблему.

1 Ответ

1 голос
/ 26 мая 2020

Вы (как разработчик) несете ответственность за то, чтобы показать что-то пользователю, это не входит в услугу SwUpdate.

Вот пример работы с MatSnackBar:

@Injectable({
  providedIn: 'root'
})
export class UpdateService {

  constructor(
    private swUpdate: SwUpdate,
    private snackbar: MatSnackBar,
    @Inject(PLATFORM_ID) platformId: string,
    appRef: ApplicationRef
  ) {
    if (isPlatformBrowser(platformId)) {
      this.swUpdate.available.subscribe(() => {
        const snack = this.snackbar.open('New version available!', 'Refresh');

        snack.onAction().pipe(switchMap(() => this.swUpdate.activateUpdate())).subscribe(() => {
          window.location.reload();
        });

        setTimeout(() => {
          snack.dismiss();
        }, 6000);
      });

      // Poll logic after isStable, otherwise isStable never fires
      appRef.isStable.pipe(
        first(stable => stable),
        switchMap(() => interval(6 * 60 * 60 * 1000)) // Every 6h
      ).subscribe(() => {
        this.swUpdate.checkForUpdate();
      });
    }
  }
}

Примечание: забудьте о platformId, если ваше приложение не поддерживает рендеринг на стороне сервера.

...