Angular2:使用浏览器返回事件关闭ng-bootstrap模式

Tom*_*mmy 11 ng-bootstrap angular

我的Angular2应用程序使用ng-bootstrap模式来详细显示一些结果图表.出于这个原因,我将模态调整为几乎全屏(仅margin: 20px左侧).这会导致某些用户使用浏览器后退按钮而不是页面右上角或底部的关闭按钮.

我现在正在尝试取消默认的浏览器返回事件,并在调用事件时关闭模式.

我在这里使用一些代码作为代码库来监听浏览器事件并用一些东西扩展它:

import { PlatformLocation } from '@angular/common'

(...)

modalRef: NgbModalRef;

constructor(location: PlatformLocation) {

    location.onPopState(() => {

        console.log('pressed back!');

        // example for a simple check if modal is opened
        if(this.modalRef !== undefined) 
        {
            console.log('modal is opened - cancel default browser event and close modal');
            // TODO: cancel the default event

            // close modal
            this.modalRef.close();
        } 
        else 
        {
            console.log('modal is not opened - default browser event');
        }
    });
}

(...)
// some code to open the modal and store the reference to this.modalRef
Run Code Online (Sandbox Code Playgroud)

问题是我不知道如何以及是否可以取消默认的返回事件.

location.onPopState((event) => {

    event.preventDefault();

});
Run Code Online (Sandbox Code Playgroud)

这实际上不起作用.该解决方案也是如此.也许我可以在打开模态时插入一些"假"历史堆栈?!

对于AngularJS 1.x,它似乎确实有效:https://stackoverflow.com/a/33454993/3623608

Tom*_*mmy 9

我实际上通过在打开模态时插入一些"假的"历史状态来解决我的问题.模态打开和模态关闭的功能如下所示:

modalRef: NgbModalRef;

open(content: NgbModal) {
    this.modalRef = this.modalService.open(content);

    // push new state to history
    history.pushState(null, null, 'modalOpened');

    this.modalRef.result.then((result) => {
        this.closeResult = `Closed with: ${result}`;
    }, (reason) => {
        this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
    });
}

private getDismissReason(reason: any): string {
    // go back in history if the modal is closed normal (ESC, backdrop click, cross click, close click)
    history.back();

    if (reason === ModalDismissReasons.ESC) {
        return 'by pressing ESC';
    } else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
        return 'by clicking on a backdrop';
    } else {
        return  `with: ${reason}`;
    }
}
Run Code Online (Sandbox Code Playgroud)

open()和getDismissReason()函数是从https://ng-bootstrap.github.io/#/components/modal"Modal with default options" 复制的.我添加的重要部分是在模态打开时推动新历史状态,并在"正常"模态关闭时回溯历史.当我们返回浏览器后退按钮时,不会调用此功能,我们会自动返回历史记录.

要确保在历史回溯事件中关闭模态,您需要以下行:

constructor(private location: PlatformLocation, private modalService: NgbModal)
{
    location.onPopState((event) => {
        // ensure that modal is opened
        if(this.modalRef !== undefined) {
            this.modalRef.close();
        }
});
Run Code Online (Sandbox Code Playgroud)

结论:当打开模态时,我们推送一个新的历史状态(例如,使用当前页面).如果模态正常关闭(使用ESC,关闭按钮,......),则手动触发历史回溯事件(我们不希望堆叠历史状态).如果历史回复事件是由浏览器触发的,我们只需要关闭模式(如果它已打开).推送的历史堆栈确保我们保持在同一页面上.

限制:添加新的历史堆栈并返回历史记录也提供了在历史中前进的机会(在关闭模态之后).这不是理想的行为.