如何在移动设备上使用"back button"关闭组件?



我创建的配置文件组件看起来像弹出窗口。组件可以显示在每个页面上(它不依赖于路由(。我想关闭它是智能手机上的"后退"按钮,所以我使用HostListener注释和window:popstate。它可以工作,但是如果我单击后退按钮ProfileComponent正在关闭,但浏览器也会转到上一页。我尝试使用preventDefault((修复它:

@HostListener('window:popstate', ['$event'])
@HostListener('window:keydown.escape')
closeProfile(event?: any) {
if(event) {
event.preventDefault();
}
this.store.dispatch(new layoutActions.CloseProfileAction());
}

但仍然不起作用。有没有办法覆盖后退按钮操作?

popstate 事件不可取消(如此处所述:https://developer.mozilla.org/en-US/docs/Web/Events/popstate(。因此,在这种情况下,预防默认不会执行任何操作。

但是,如果您想留在页面上,实际上阻止后退按钮并关闭配置文件弹出窗口,您可以执行以下操作。

@HostListener('window:popstate', ['$event'])
@HostListener('window:keydown.escape')
closeProfile(event?: any) {
history.go(1);
this.store.dispatch(new layoutActions.CloseProfileAction());
}

希望这有帮助。

按下后退按钮将导致历史记录状态弹出。

因此,您可以做的是在打开模态后向历史堆栈添加"模态状态":

history.pushState({ modal: true }, '');

比当按下后退按钮时,这个"模态状态"不是弹出上一页的状态(并返回它(,而是弹出的状态,当前加载的页面不会有任何变化。

以下代码演示如何使用ngx-boostrap模态执行此操作,并且可以轻松适应其他模态实现:

在线演示:https://angular12-bootstrap-bkyuq7.stackblitz.io/

堆栈闪电战来源:https://stackblitz.com/edit/angular12-bootstrap-bkyuq7

组件打字稿:

import { Component, HostListener } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal.module';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
private modal?: NgbModalRef;
constructor(private modalService: NgbModal) {}
@HostListener('window:popstate', ['$event'])
onPopState(event: any): void {
console.log('back button pressed');
this.modal?.close();
}
openBootstrapModal(modal: any): void {
this.modal = this.modalService.open(modal);
this.pushModalStateIntoHistory();
this.modal.closed.subscribe(() => {
this.modal = undefined;
});
}
private pushModalStateIntoHistory(): void {
history.pushState({ modal: true }, '');
}
}

.HTML:

<div>
<button class="btn btn-sm btn-outline-primary" (click)="openBootstrapModal(demoModal)">
Launch demo modal
</button>
<ng-template #demoModal let-modal>
<div class="modal-header">
My Modal
<button (click)="modal.dismiss()">x</button>
</div>
<div class="modal-body">Modal content.</div>
</ng-template>
</div>

为了完整起见,可以考虑在为组件调用ngOnDestroy方法时从历史记录堆栈中弹出modal state

ngOnDestroy(): void {
if (this.modal) {
this.modal.close();
this.popModalStateFromHistory();
}
}
private popModalStateFromHistory(): void {
if (window.history.state.modal) {
history.back();
}
}

最新更新