【问题标题】:Close angular modal and remain on same page on back button click关闭角度模态并在后退按钮单击时保持在同一页面上
【发布时间】:2018-08-07 14:53:27
【问题描述】:

我正在使用 Angular 6 开发一个使用 Angular 模态的 Web 应用程序。在我的手机(Android)上,我注意到在打开模式时单击手机的后退按钮不仅会关闭打开的模式,还会导航回上一页。是否可以只关闭打开的对话框并保留在主页上?我认为这将是手机上的预期行为。

谢谢!

【问题讨论】:

  • 您使用的是哪个组件库?您提到“角度模态”,但这是 Bootstrap、Material 等的一部分吗?
  • 我正在使用 Material Modal
  • JS上没有“返回按钮”事件,返回按钮总是会导航回上一页。
  • @Danny908,我认为 Simo 使用 Cordova 或其他框架来制作应用程序。 Cordova 将 web 应用程序转换为 movil 应用程序,允许控制相机、GPS、后退按钮等,请参阅cordova.apache.org/docs/en/latest

标签: angular


【解决方案1】:

@Simo,有点复杂。在 Cordova 中,您有一个事件“deviceready”,您可以使用它来控制事件暂停、恢复和后退按钮。

阅读官方文档,将 Web 应用程序转换为 movil 应用程序。

您可以看到 Cordova 将新事件添加到“文档”。 https://cordova.apache.org/docs/en/latest/cordova/events/events.html

那么如何将它添加到我们的 Angular 应用程序中?

对我来说,最好的方法是更改​​ AppComponent(主组件)以添加新事件并使用服务使所有流程透明。

在 AppComponent(主组件)的 AfterViewInit 中,我们将添加 document.addEventListener 用于准备、暂停、恢复和后退按钮

//we use a enum for the different events.
export enum CordovaEvent {BackButton,Resume,Pause}

export class AppComponent implements AfterViewInit{

  constructor(private cordovaEventService:CordovaEventService) { }

  ngAfterViewInit() {
    document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
  }
  onDeviceReady() {
    // Control pause, resume and backbutton
    document.addEventListener('pause', this.onPause.bind(this), false);
    document.addEventListener('resume', this.onResume.bind(this), false);
    document.addEventListener("backbutton", this.onBackKeyDown.bind(this), false);
    //a variable that I can use to know if is really a movil application 
    this.cordovaEventService.isCordoba=true;

  };

  onPause() {
    //the only thing that I make is execute a function in a service
    this.cordovaEventService.sendEvent(CordovaEvent.Pause);
  };

  onResume() {
    this.cordovaEventService.sendEvent(CordovaEvent.Resume);
  };

  onBackKeyDown(e) {
    this.cordovaEventService.sendEvent(CordovaEvent.BackButton);
    e.preventDefault();
    e.stopPropagation();

  };
}

我们的服务非常简单。只是一个私有主题和一个可以订阅我们组件的 Observable。

@Injectable()

export class CordovaEventService {

    private listeningSource:Subject<CordovaEvent>=new Subject<CordovaEvent>();
    cordovaEvent:Observable<CordovaEvent>=this.listeningSource.asObservable();

    isCordoba:boolean=false;

    constructor() {
    }
    sendEvent(evento:CordovaEvent)
    {
        this.listeningSource.next(evento);
    }
}

最后,任何组件都可以在ngOnInit中订阅cordovaEvent

  ngOnInit() {
    this.cordovaEventService.cordovaEvent.subscribe((evento: CordovaEvent) => {
      if (evento == CordovaEvent.BackButton) {
        this.ngZone.run(()=>{
          ....make something...
        })
      }
    });
  }

【讨论】:

  • 谢谢@Eliseo。我实际上要问的是当我在 Chrome 等浏览器上关闭对话框时阻止导航的能力。我没有使用 Cordova。
  • 由于我询问的行为看起来无法实现,我将接受@Eliseo 的回答,以防有人想使用 Cordova。
【解决方案2】:

我试过了,它似乎可以工作

// push history state when a dialog is opened
dialogRef.afterOpened.subscribe((ref: MatDialogRef<any, any>) => {
  window.history.pushState(ref.id, '');
  // pop from history if dialog has not been closed with back button, and gurrent state is still ref.id
  ref.afterClosed().subscribe(() => {
    if (history.state === ref.id) {
      window.history.go(-1);
    }
  });
});

【讨论】:

    【解决方案3】:

    试试这个

    import { Router, Event } from '@angular/router';  
    
    constructor(private router: Router) {
        this.router.events.subscribe((event: Event) => {
          $(".modal").modal('hide');
        });
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-21
      • 2021-05-31
      • 1970-01-01
      • 1970-01-01
      • 2017-06-25
      相关资源
      最近更新 更多