简体   繁体   English

如何处理使用Ionic3开发的PWA中的硬件后退按钮

[英]How to handle hardware back button in PWA developed using Ionic3

I have developed a PWA (Tab based) using Ionic 3. It is working fine until hardware back button or browser's back button is pressed in android browser. 我使用Ionic 3开发了一个PWA(基于Tab)。它在Android浏览器中按下硬件后退按钮或浏览器后退按钮之前工作正常。 If it is running from home screen, pressing hardware back will close app. 如果它从主屏幕运行,按回硬件将关闭应用程序。 If app is running in chrome in android (only tested in chrome), hardware back or browser's back will reload PWA's first page, not previously visited page. 如果应用程序在android中运行chrome(仅在chrome中测试),硬件返回或浏览器的后面将重新加载PWA的第一页,而不是之前访问过的页面。 How to handle these events in Ionic 3 PWA? 如何在Ionic 3 PWA中处理这些事件?

I am using lazy load for all pages. 我正在为所有页面使用延迟加载。

What I tried so far: 到目前为止我尝试了什么:

  1. As per jgw96's comment here , I thought IonicPage will handle navigation itself. 按照jgw96的评论在这里 ,我想IonicPage将处理导航本身。 But it is not working. 但它没有用。

  2. Used platform.registerBackButtonAction, but it's not for PWA. 使用platform.registerBackButtonAction,但它不适用于PWA。

  3. As per Webruster's suggestion below in Answers, tried code in app.component.ts. 根据Webruster在Answers中的建议,在app.component.ts中尝试了代码。 But no change. 但没有变化。

Posting code: 发布代码:

    import { Component, ViewChild } from '@angular/core';
    import { Nav, Platform, AlertController, Alert, Events, App, IonicApp, MenuController } from 'ionic-angular';

    @Component({
      templateUrl: 'app.html'
    })
    export class MyApp {
      @ViewChild(Nav) nav: Nav;
      rootPage:any = 'TabsPage';
      constructor(public platform: Platform,
        public alertCtrl: AlertController, public events: Events,
          public menu: MenuController,
          private _app: App,
          private _ionicApp: IonicApp) {

        platform.ready().then(() => {
          this.configureBkBtnprocess ();
        });
      }

      configureBkBtnprocess() {
        if (window.location.protocol !== "file:") {
          window.onpopstate = (evt) => {
            if (this.menu.isOpen()) {
              this.menu.close ();
              return;
            }
    let activePortal = this._ionicApp._loadingPortal.getActive() ||
      this._ionicApp._modalPortal.getActive() ||
      this._ionicApp._toastPortal.getActive() ||
      this._ionicApp._overlayPortal.getActive();

    if (activePortal) {
      activePortal.dismiss();
      return;
    }

    if (this._app.getRootNav().canGoBack())
      this._app.getRootNav().pop();
          };

          this._app.viewDidEnter.subscribe((app) => {
            history.pushState (null, null, "");
            });
        }
      }
    }

you have mentioned that you are working with the hardware back button on app and in browser so you didn't mention clearly what need to be done at what stage so i came up with the generalized solution which can be useful in most of the cases 你已经提到你正在使用应用程序和浏览器中的硬件后退按钮,所以你没有清楚地提到在什么阶段需要做什么,所以我提出了在大多数情况下都有用的通用解决方案

app.component.ts app.component.ts

platform.ready().then(() => {

      // your other plugins code...
      this.configureBkBtnprocess ();

    });

configureBkBtnprocess configureBkBtnprocess

private configureBkBtnprocess () {

    // If you are on chrome (browser)
    if (window.location.protocol !== "file:") {

      // Register browser back button action and you can perform
      // your own actions like as follows
      window.onpopstate = (evt) => {

        // Close menu if open
        if (this._menu.isOpen()) {
          this._menu.close ();
          return;
        }

        // Close any active modals or overlays
        let activePortal = this._ionicApp._loadingPortal.getActive() ||
          this._ionicApp._modalPortal.getActive() ||
          this._ionicApp._toastPortal.getActive() ||
          this._ionicApp._overlayPortal.getActive();

        if (activePortal) {
          activePortal.dismiss();
          return;
        }

        // Navigate back
        if (this._app.getRootNav().canGoBack()) 
        this._app.getRootNav().pop();

      }
      else{
        // you are in the app
      };

  // Fake browser history on each view enter
  this._app.viewDidEnter.subscribe((app) => {
    history.pushState (null, null, "");
  });

Solution 2 Try to Add the these event listener in the platform ready: 解决方案2尝试在平台准备中添加这些事件侦听器:

 window.addEventListener('load', function() { window.history.pushState({}, '') 
           })
    window.addEventListener('popstate', function() { window.history.pushState({}, 
   '') })

I have pretty much same requirement but none of the solution completely works, so i came up with my own. 我有几乎相同的要求,但没有一个解决方案完全有效,所以我想出了自己的。 here i have used an array to keep track of visited page and removes it on back click event. 在这里,我使用了一个数组来跟踪访问过的页面,并在后退点击事件中删除它。

Note: window.onpopstate gets called even on pushing new page 注意:即使在推送新页面时也会调用window.onpopstate

import { Platform, Nav } from "ionic-angular";
import { HomePage } from "../pages/home/home";
@Component({
  templateUrl: "app.html"
})
export class MyApp {
  rootPage: any;
  @ViewChild(Nav) nav: Nav;
  pageHistory: string[] = [];//to track page history

  constructor(
    platform: Platform,
    statusBar: StatusBar,
    splashScreen: SplashScreen
  ) {

    window.addEventListener("load", function() {
    //adding a state to prevent app exit on back
      window.history.pushState({ noBackExitsApp: true }, "");
    });

    platform.ready().then(() => {
      window.onpopstate = evt => {
        let view = this.nav.getActive();
        if (this.pageHistory.find(x => x === view.name)) {
          if (!view.name.startsWith("Home")) {//handle a condition where you want to go back
            this.pageHistory = this.pageHistory.filter(n => n !== view.name);
            this.nav.pop().catch(reason => {
              console.log("Unable to pop :" + reason);
            });
          }
        } else {
          window.history.pushState({ noBackExitsApp: true }, "");
          this.pageHistory.push(view.name);
        }
      };

      this.rootPage = HomePage;
      statusBar.styleDefault();
      splashScreen.hide();
    });
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM