我已经使用离子3开发了一个PWA(基于TAB)。它的工作正常,直到硬件后按钮或浏览器的后退按钮在Android浏览器中按下。如果它是从主屏幕运行的,那么按硬件返回将关闭应用程序。如果应用程序在Android中(仅在Chrome中进行测试)在Chrome中运行,则硬件背部或浏览器的背部将重新加载PWA的第一页,而不是以前访问的页面。如何在离子3 PWA中处理这些事件?
我在所有页面上都使用懒负载。
我到目前为止尝试的是:
-
根据JGW96在这里的评论,我认为Ionicpage将处理导航本身。但这是行不通的。
-
使用Platform.RegisterBackButtonAction,但不适合PWA。
-
根据Webruster在下面的建议,在App.component.ts中尝试的代码。但是没有变化。
发布代码:
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, "");
});
}
}
}
您已经提到您正在使用应用程序和浏览器上的硬件返回按钮,因此您没有清楚地提及在哪个阶段需要做什么,所以我想到了广义在大多数情况下可能有用的解决方案
app.component.ts
platform.ready().then(() => {
// your other plugins code...
this.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, "");
});
解决方案2 尝试将这些事件侦听器添加到平台上准备:
: window.addEventListener('load', function() { window.history.pushState({}, '')
})
window.addEventListener('popstate', function() { window.history.pushState({},
'') })
我有几乎相同的要求,但是解决方案都没有完全奏效,所以我想出了自己的要求。在这里,我使用一个数组来跟踪访问的页面并在"背点击事件"中删除它。
注意: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();
});
}
}