我的硬件 'Back Button Action' 在 Ionic 4 中不工作
My Hardware 'Back Button Action' is not working in Ionic 4
我正在使用我的 Ionic 4 应用程序,当用户在移动设备后退按钮上单击 2 次时,它应该会关闭该应用程序,但这并没有发生。
这是我的app.component.ts:
lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;
constructor(){
this.backButtonEvent();
}
backButtonEvent() {
document.addEventListener("backbutton", () => {
this.routerOutlets.forEach((outlet: IonRouterOutlet) => {
if (outlet && outlet.canGoBack()) {
outlet.pop();
} else if (this.router.url === '/tabs/tab1') {
if (new Date().getTime() - this.lastTimeBackPress < this.timePeriodToExit) {
navigator['app'].exitApp(); //Exit from app
} else {
this.presentAlertConfirm();
this.lastTimeBackPress = new Date().getTime();
}
// navigator['app'].exitApp(); // work for ionic 4
}
});
});
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
// header: 'Confirm!',
message: 'Are you sure you want to exit the app?',
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: (blah) => {
}
}, {
text: 'Close App',
handler: () => {
navigator['app'].exitApp();
}
}
]
});
await alert.present();
}
当我在首页 (Tab1) 时,它可以工作,而当我在其他选项卡时,它不工作,也不会转到首页。
我认为问题出在我的 (outlet && outlet.canGoBack())
因为这不起作用。我正在使用选项卡主题,当用户没有其他选项卡并单击硬件后退按钮。
I am using Ionic 4 tab theme.
非常感谢任何帮助。
那是因为您在平台准备就绪之前调用了 registerBackButtonAction。平台准备就绪后,您必须订阅后退按钮。一个接近:
this.platform.ready().then(
() => {
this.platform.registerBackButtonAction(() => {
this.platform.exitApp();
});
}
);
这样做。
constructor(private platform: Platform) {
this.platform.backButton.subscribe(() => {
});
}
试试这个:
lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList < IonRouterOutlet > ;
backButtonEvent() {
document.addEventListener("backbutton", async() => {
try {
const element = await this.modalCtrl.getTop();
if (element) {
element.dismiss();
return;
}
} catch (error) {
console.log(error);
}
this.routerOutlets.forEach(async(outlet: IonRouterOutlet) => {
if (this.router.url != '/tabs/tab1') {
await this.router.navigate(['/tabs/tab1']);
} else if (this.router.url === '/tabs/tab1') {
if (new Date().getTime() - this.lastTimeBackPress >= this.timePeriodToExit) {
await this.presentAlertConfirm();
this.lastTimeBackPress = new Date().getTime();
}
navigator['app'].exitApp(); // work for ionic 4
}
});
});
}
并在构造函数中调用这个函数。这解决了我的问题,因为我正在使用选项卡主题并且 outlet.pop();
不工作。所以我尝试了这个方法。
为了回应@Raghav 的评论,我会这样尝试:
lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList < IonRouterOutlet > ;
constructor(private platform: Platform) {
this.backButtonEvent();
}
backButtonEvent() {
this.platform.backButton.subscribeWithPriority(0, () => {
this.routerOutlets.forEach(async(outlet: IonRouterOutlet) => {
if (this.router.url != '/tabs/tab1') {
await this.router.navigate(['/tabs/tab1']);
} else if (this.router.url === '/tabs/tab1') {
if (new Date().getTime() - this.lastTimeBackPress >= this.timePeriodToExit) {
this.lastTimeBackPress = new Date().getTime();
this.presentAlertConfirm();
} else {
navigator['app'].exitApp();
}
}
});
});
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
// header: 'Confirm!',
message: 'Are you sure you want to exit the app?',
buttons: [{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: (blah) => {}
}, {
text: 'Close App',
handler: () => {
navigator['app'].exitApp();
}
}]
});
await alert.present();
}
在您的 app.component.ts
中试试这个
lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChild(IonRouterOutlet, { static: false }) routerOutlets: IonRouterOutlet
constractor( private router: Router, private alertController: AlertController){this.backbutton()}
backbutton() {
console.log('backbutton')
document.addEventListener("backbutton", () => {
console.log('backbutton1')
if (this.routerOutlets && this.routerOutlets.canGoBack()) {
this.routerOutlets.pop();
}
// else if (this.router.url != '/tabs/tabs/tab1') {
// this.router.navigate(['/tabs/tabs/tab1']);
// }
else if (this.router.url === '/home') {
if (new Date().getTime() - this.lastTimeBackPress >= this.timePeriodToExit) {
this.lastTimeBackPress = new Date().getTime();
this.presentAlertConfirm();
} else {
navigator['app'].exitApp();
}
}
});
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
// header: 'Confirm!',
message: 'Are you sure you want to exit the app?',
buttons: [{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: (blah) => { }
}, {
text: 'Close App',
handler: () => {
navigator['app'].exitApp();
}
}]
});
await alert.present();
}
您也可以尝试以下代码片段,
Make a change or add code like this in your app.component.ts file
import { Component, ViewChildren, QueryList } from '@angular/core';
import { Platform, IonRouterOutlet, ToastController } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
//code for exit app
// set up hardware back button event.
lastTimeBackPress = 0;
timePeriodToExit = 2000;
//code for exit app
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private toastController: ToastController,
private router: Router
) {
this.initializeApp();
// Initialize BackButton Eevent.
this.backButtonEvent();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleLightContent();
this.splashScreen.hide();
});
}
// active hardware back button
backButtonEvent() {
this.platform.backButton.subscribe(async () => {
this.routerOutlets.forEach(async (outlet: IonRouterOutlet) => {
if (outlet && outlet.canGoBack()) {
outlet.pop();
} else if (this.router.url === '/home') {
if (new Date().getTime() - this.lastTimeBackPress < this.timePeriodToExit) {
// this.platform.exitApp(); // Exit from app
navigator['app'].exitApp(); // work in ionic 4
} else {
const toast = await this.toastController.create({
message: 'Press back again to exit App.',
duration: 2000,
position: 'middle'
});
toast.present();
// console.log(JSON.stringify(toast));
this.lastTimeBackPress = new Date().getTime();
}
}
});
});
}
}
Make a change or add code like this in your home.ts file or where you want to user exit from your app page.
import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
public subscription: any;
constructor(private platform: Platform) { }
ionViewDidEnter() {
this.subscription = this.platform.backButton.subscribe(() => {
navigator['app'].exitApp();
});
}
ionViewWillLeave() {
this.subscription.unsubscribe();
}
}
试试这个
import {Component, QueryList, ViewChildren} from '@angular/core';
import {IonRouterOutlet, Platform, ToastController} from '@ionic/angular';
import {SplashScreen} from '@ionic-native/splash-screen/ngx';
import {StatusBar} from '@ionic-native/status-bar/ngx';
import {Router} from '@angular/router';
import {Location} from '@angular/common';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
lastTimeBackPress = 0;
timePeriodToExit = 2000;
// @ts-ignore
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private toastController: ToastController,
private router: Router,
private location: Location
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.backButtonEvent();
});
}
// active hardware back button
backButtonEvent() {
this.platform.backButton.subscribeWithPriority(0, () => {
this.routerOutlets.forEach(async () => {
if (this.router.url !== '/tabs/home') {
await this.location.back();
} else {
if (new Date().getTime() - this.lastTimeBackPress < this.timePeriodToExit) {
navigator['app'].exitApp(); // work in ionic 4
} else {
const toast = await this.toastController.create({
message: 'Press back again to exit App.',
duration: 2000,
position: 'middle'
});
toast.present();
// console.log(JSON.stringify(toast));
this.lastTimeBackPress = new Date().getTime();
}
}
});
});
}
}
我正在使用我的 Ionic 4 应用程序,当用户在移动设备后退按钮上单击 2 次时,它应该会关闭该应用程序,但这并没有发生。
这是我的app.component.ts:
lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;
constructor(){
this.backButtonEvent();
}
backButtonEvent() {
document.addEventListener("backbutton", () => {
this.routerOutlets.forEach((outlet: IonRouterOutlet) => {
if (outlet && outlet.canGoBack()) {
outlet.pop();
} else if (this.router.url === '/tabs/tab1') {
if (new Date().getTime() - this.lastTimeBackPress < this.timePeriodToExit) {
navigator['app'].exitApp(); //Exit from app
} else {
this.presentAlertConfirm();
this.lastTimeBackPress = new Date().getTime();
}
// navigator['app'].exitApp(); // work for ionic 4
}
});
});
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
// header: 'Confirm!',
message: 'Are you sure you want to exit the app?',
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: (blah) => {
}
}, {
text: 'Close App',
handler: () => {
navigator['app'].exitApp();
}
}
]
});
await alert.present();
}
当我在首页 (Tab1) 时,它可以工作,而当我在其他选项卡时,它不工作,也不会转到首页。
我认为问题出在我的 (outlet && outlet.canGoBack())
因为这不起作用。我正在使用选项卡主题,当用户没有其他选项卡并单击硬件后退按钮。
I am using Ionic 4 tab theme.
非常感谢任何帮助。
那是因为您在平台准备就绪之前调用了 registerBackButtonAction。平台准备就绪后,您必须订阅后退按钮。一个接近:
this.platform.ready().then(
() => {
this.platform.registerBackButtonAction(() => {
this.platform.exitApp();
});
}
);
这样做。
constructor(private platform: Platform) {
this.platform.backButton.subscribe(() => {
});
}
试试这个:
lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList < IonRouterOutlet > ;
backButtonEvent() {
document.addEventListener("backbutton", async() => {
try {
const element = await this.modalCtrl.getTop();
if (element) {
element.dismiss();
return;
}
} catch (error) {
console.log(error);
}
this.routerOutlets.forEach(async(outlet: IonRouterOutlet) => {
if (this.router.url != '/tabs/tab1') {
await this.router.navigate(['/tabs/tab1']);
} else if (this.router.url === '/tabs/tab1') {
if (new Date().getTime() - this.lastTimeBackPress >= this.timePeriodToExit) {
await this.presentAlertConfirm();
this.lastTimeBackPress = new Date().getTime();
}
navigator['app'].exitApp(); // work for ionic 4
}
});
});
}
并在构造函数中调用这个函数。这解决了我的问题,因为我正在使用选项卡主题并且 outlet.pop();
不工作。所以我尝试了这个方法。
为了回应@Raghav 的评论,我会这样尝试:
lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList < IonRouterOutlet > ;
constructor(private platform: Platform) {
this.backButtonEvent();
}
backButtonEvent() {
this.platform.backButton.subscribeWithPriority(0, () => {
this.routerOutlets.forEach(async(outlet: IonRouterOutlet) => {
if (this.router.url != '/tabs/tab1') {
await this.router.navigate(['/tabs/tab1']);
} else if (this.router.url === '/tabs/tab1') {
if (new Date().getTime() - this.lastTimeBackPress >= this.timePeriodToExit) {
this.lastTimeBackPress = new Date().getTime();
this.presentAlertConfirm();
} else {
navigator['app'].exitApp();
}
}
});
});
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
// header: 'Confirm!',
message: 'Are you sure you want to exit the app?',
buttons: [{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: (blah) => {}
}, {
text: 'Close App',
handler: () => {
navigator['app'].exitApp();
}
}]
});
await alert.present();
}
在您的 app.component.ts
中试试这个 lastTimeBackPress = 0;
timePeriodToExit = 2000;
@ViewChild(IonRouterOutlet, { static: false }) routerOutlets: IonRouterOutlet
constractor( private router: Router, private alertController: AlertController){this.backbutton()}
backbutton() {
console.log('backbutton')
document.addEventListener("backbutton", () => {
console.log('backbutton1')
if (this.routerOutlets && this.routerOutlets.canGoBack()) {
this.routerOutlets.pop();
}
// else if (this.router.url != '/tabs/tabs/tab1') {
// this.router.navigate(['/tabs/tabs/tab1']);
// }
else if (this.router.url === '/home') {
if (new Date().getTime() - this.lastTimeBackPress >= this.timePeriodToExit) {
this.lastTimeBackPress = new Date().getTime();
this.presentAlertConfirm();
} else {
navigator['app'].exitApp();
}
}
});
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
// header: 'Confirm!',
message: 'Are you sure you want to exit the app?',
buttons: [{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: (blah) => { }
}, {
text: 'Close App',
handler: () => {
navigator['app'].exitApp();
}
}]
});
await alert.present();
}
您也可以尝试以下代码片段,
Make a change or add code like this in your app.component.ts file
import { Component, ViewChildren, QueryList } from '@angular/core';
import { Platform, IonRouterOutlet, ToastController } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
//code for exit app
// set up hardware back button event.
lastTimeBackPress = 0;
timePeriodToExit = 2000;
//code for exit app
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private toastController: ToastController,
private router: Router
) {
this.initializeApp();
// Initialize BackButton Eevent.
this.backButtonEvent();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleLightContent();
this.splashScreen.hide();
});
}
// active hardware back button
backButtonEvent() {
this.platform.backButton.subscribe(async () => {
this.routerOutlets.forEach(async (outlet: IonRouterOutlet) => {
if (outlet && outlet.canGoBack()) {
outlet.pop();
} else if (this.router.url === '/home') {
if (new Date().getTime() - this.lastTimeBackPress < this.timePeriodToExit) {
// this.platform.exitApp(); // Exit from app
navigator['app'].exitApp(); // work in ionic 4
} else {
const toast = await this.toastController.create({
message: 'Press back again to exit App.',
duration: 2000,
position: 'middle'
});
toast.present();
// console.log(JSON.stringify(toast));
this.lastTimeBackPress = new Date().getTime();
}
}
});
});
}
}
Make a change or add code like this in your home.ts file or where you want to user exit from your app page.
import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
public subscription: any;
constructor(private platform: Platform) { }
ionViewDidEnter() {
this.subscription = this.platform.backButton.subscribe(() => {
navigator['app'].exitApp();
});
}
ionViewWillLeave() {
this.subscription.unsubscribe();
}
}
试试这个
import {Component, QueryList, ViewChildren} from '@angular/core';
import {IonRouterOutlet, Platform, ToastController} from '@ionic/angular';
import {SplashScreen} from '@ionic-native/splash-screen/ngx';
import {StatusBar} from '@ionic-native/status-bar/ngx';
import {Router} from '@angular/router';
import {Location} from '@angular/common';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
lastTimeBackPress = 0;
timePeriodToExit = 2000;
// @ts-ignore
@ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private toastController: ToastController,
private router: Router,
private location: Location
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.backButtonEvent();
});
}
// active hardware back button
backButtonEvent() {
this.platform.backButton.subscribeWithPriority(0, () => {
this.routerOutlets.forEach(async () => {
if (this.router.url !== '/tabs/home') {
await this.location.back();
} else {
if (new Date().getTime() - this.lastTimeBackPress < this.timePeriodToExit) {
navigator['app'].exitApp(); // work in ionic 4
} else {
const toast = await this.toastController.create({
message: 'Press back again to exit App.',
duration: 2000,
position: 'middle'
});
toast.present();
// console.log(JSON.stringify(toast));
this.lastTimeBackPress = new Date().getTime();
}
}
});
});
}
}