Ionic 如何使用Angular 7覆盖离子4中的离子返回按钮操作

tuwxkamq  于 2022-12-09  发布在  Ionic
关注(0)|答案(5)|浏览(192)

当用户点击ion-back-button时,我想停止从一个页面到另一个页面的导航。我需要根据哪个应用程序决定是否允许后退操作来执行一些验证/检查。

pxy2qtax

pxy2qtax1#

使用IonBackButtonDelegate覆盖该功能。

import { IonBackButtonDelegate } from '@ionic/angular';

...

export class TestPage {

  @ViewChild(IonBackButtonDelegate, { static: false }) backButton: IonBackButtonDelegate;

  ...
  // Registering
  ionViewDidEnter() {
    console.log('ionViewDidEnter');
    this.setUIBackButtonAction();
  }

  setUIBackButtonAction() {
    this.backButton.onClick = () => {
      // handle custom action here
    };
  }
}
iszxjhcz

iszxjhcz2#

这可以通过离子生命周期挂钩完成
离子视图ID加载:仅当视图存储在内存中时触发。此事件不会在进入已缓存的视图时触发。这是初始化相关任务的好地方。ionViewWillEnter:当进入一个页面时,在它成为活动页面之前,它被触发。使用它来完成每次进入视图时要执行的任务(设置事件监听器,更新表格等)。
离子视图ID输入:当进入一个页面时,在该页面成为活动页面后触发。与前一个非常相似。
离子视图将离开:当您离开页面时,在它停止为使用中页面之前引发。使用它来行程每次离开页面时需要执行的事情(停用事件侦听程式等)。
离子视图未离开:当您离开一个页面时引发,在该页面不再是活动页面之后。与上一个类似。
ionView将卸载:当要完全删除视图时激发(在离开非缓存视图后)。

作为奖金轨道,有两个其他强大的方法与这些事件:这些方法主要用于视图访问控制(用于身份验证)。

导航防护如果要阻止用户离开视图:

export class MyClass{
 constructor(
   public navCtrl: NavController
  ){}

  pushPage(){
    this.navCtrl.push(DetailPage);
  }

  ionViewCanLeave(): boolean{
   // here we can either return true or false
   // depending on if we want to leave this view
   if(isValid(randomValue)){
      return true;
    } else {
      return false;
    }
  }
}

离子视图可以输入:在进入视图之前激发,允许您控制是否可以访问视图(返回true或false)。
离子视图可以离开:在离开视图之前触发,允许您控制是否可以离开视图。
需要强调的是,导航保护在任何其他生命周期事件方法之前执行。

fcwjkofz

fcwjkofz3#

我找不到一个只有控制器的解决方案(ionViewCanLeave没有触发)--我目前的破解方法如下。它有条件地阻止/覆盖ion-back-button,同时仍然在单击时激活按钮。
于飞:

<ion-back-button defaultHref="/" routerDirection="back">
    <div (click)="back($event)"></div>
</ion-back-button>

SCSS:

ion-back-button {
    & > div {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        z-index: 1;
    }
}

技术支持:

public back($event) {
    if (shouldPreventBack)
        $event.stopPropagation();
}
lyr7nygr

lyr7nygr4#

还有另一种替代方法,可能会使用Angular 事件产生更多natural解决方案:)
我们所需要做的就是创建一个Directive,它使用@HostIonBackButtonDelegate来覆盖内置的ionic ion-back-button指令本身,如果有任何观察者在监听它,则触发一个新的backClicked: InterceptedEvent
从技术上讲,我们不需要触发自定义事件/类型,我们可以只触发事件本身,然后在执行单击处理程序之前检查event.defaultPrevented,但是......下面的方法通过回调模式支持async事件侦听器。

import { AfterViewInit, Directive, EventEmitter, Host, HostListener, Output } from '@angular/core';
import { IonBackButtonDelegate } from '@ionic/angular';

import { InterceptedEvent } from '../../model';

export interface InterceptedEvent {
  native: Event;
  proceed: () => void;
}

/**
 * Overrides the default ion-back-button directive.
 * @see https://github.com/ionic-team/ionic-framework/blob/main/angular/src/directives/navigation/ion-back-button.ts
 */
@Directive({
  selector: 'ion-back-button',
})
export class IonBackButtonOverrideDirective implements AfterViewInit {

  @Output()
  backClicked = new EventEmitter<InterceptedEvent>();

  private delegate: (ev: Event) => void;

  constructor(
    @Host() private host: IonBackButtonDelegate
  ) { }

  ngAfterViewInit(): void {
    if (this.backClicked.observed) {
      // This is where we wrap/delegate the default behavior of the Ionic directive
      this.delegate = this.host.onClick;
      this.host.onClick = () => { };
    }
  }

  @HostListener('click', ['$event'])
  async onClick(event: Event) {
    let executed = false;
    this.backClicked.emit({
      native: event,
      proceed: () => {
        if (!executed) {
          executed = true;
          this.delegate.apply(this.host, [event]);
        }
      }
    });
  }
}

当然,您需要确保在您的模块中正确地注册了此内容。

@NgModule({
  declarations: [IonBackButtonOverrideDirective],
  ...

您的消费代码将需要使用新的(backClicked)事件:

<ion-back-button (backClicked)="onBackClicked($event)"></ion-back-button>

如果你想让后退按钮执行它原来的工作,你需要调用InterceptedEvent.proceed()

handleBackClicked(event: InterceptedEvent) {
      if (ignore event) {
        ... do your work here
      } else {
        event.proceed();
      }
  }

一切都是类型安全的,不需要使用其他离子生命周期事件。
还有很多其他的方法来构造事件,比如使用event.preventDefault()本身来避免调用proceed(),但是回调方法支持我所需要的大多数用例,比如async方法等等。
我肯定有更干净的方法。感谢反馈!

pexxcrt2

pexxcrt25#

试试这个:
于飞:

<ion-buttons slot="left">
            <ion-back-button (click)="BackButtonAction()">Back</ion-back-button>
 </ion-buttons>

技术支持:

BackButtonAction(){
    //action to be performed on back button
}

相关问题