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

时间:2017-12-06 12:25:07

标签: android ionic-framework

我使用Ionic 3开发了一个PWA(基于Tab)。它在Android浏览器中按下硬件后退按钮或浏览器的后退按钮之前工作正常。如果它从主屏幕运行,按回硬件将关闭应用程序。如果应用程序在android中运行chrome(仅在chrome中测试),硬件返回或浏览器的后面将重新加载PWA的第一页,而不是以前访问过的页面。如何在Ionic 3 PWA中处理这些事件?

我正在为所有页面使用延迟加载。

到目前为止我尝试了什么:

  1. 根据jgw96的评论here,我认为IonicPage将自己处理导航。但它没有用。

  2. 使用了platform.registerBackButtonAction,但它不适用于PWA。

  3. 根据Webruster在Answers中的建议,尝试了app.component.ts中的代码。但没有变化。

  4. 发布代码:

        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, "");
                });
            }
          }
        }
    

2 个答案:

答案 0 :(得分:6)

你提到你正在使用应用程序和浏览器中的硬件后退按钮,所以你没有清楚地提到在什么阶段需要做什么,所以我想出了广泛的解决方案,这在大多数情况下是有用的案件

<强> 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({}, 
   '') })

答案 1 :(得分:0)

我有几乎相同的要求,但是没有一种解决方案能完全起作用,所以我提出了自己的解决方案。在这里,我使用了一个数组来跟踪已访问页面,并在发生单击事件时将其删除。

注意: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(); }); } } 即使在推送新页面时也会被调用

file_names = ["#{fileNameFromUser}"]

file_names.each do |file_name|
 text = File.read(file_name)
 replacedcontent = text.gsub(/textToReplace/, "#{ReplaceWithThis}")
 replacedcontent += text.gsub(/textToReplace2/, "#{ReplaceWithThis2}")

# To write changes to the file, use:
File.open(file_name, "w") {|file| file.puts replacedcontent}
end