在 beforeunload 事件之前的 Angular8 IFrame

Angular8 IFrame before beforeunload event

我有一个 angular 应用程序,它是一种在其中托管子应用程序的主应用程序。子应用程序也是 angular 个应用程序。我加载子应用程序的方式是通过 Iframes。

子应用程序显示为列表,当我单击一个选项卡时,该应用程序被加载。当我对应用程序中的数据进行一些更改时,如果我单击另一个子选项卡,我想显示一条警告消息说“更改将丢失”。我可以通过使用 beforeunload 事件来实现它,如下所示。我可以检查是否有任何未保存的更改并显示警告弹出窗口。

  @HostListener('window:beforeunload', ['$event'])
  unloadNotification($event: any) {
      if (**my logic here) {
          $event.returnValue =true;
      }
  }

唯一的问题是,当我单击另一个子选项卡时,主机应用程序突出显示该子选项卡,然后显示警告弹出窗口。如果我单击弹出窗口上的停留按钮,我可以进入我想要的子选项卡,但在主机应用程序上,另一个子选项卡会突出显示。因此,如果我想留在当前子选项卡上,我试图找到一种不突出显示其他选项卡的方法。 beforeunload之前的东西。

我的理解是,您必须更新现有项目,该项目的构建方式采用 beforeunload 事件来实现类似于 Angular 功能的功能,称为路由守卫。您加载或不加载选定的 iframe 取决于您在 beforeunload 事件的帮助下实现的逻辑。您似乎不赞成更改此实现,这就是为什么要寻求涵盖您的要求的解决方案uirement 应用与另一个 window 事件类似的方法。

如果我的理解是正确的,您需要重构此实现,以便 "guarding" 的发生取决于 "host application" 的内部工作原理,它实际上必须放在首位。您遇到的问题是因为当 iframe 的卸载事件被取消时,主机应用程序的取消选项卡已经被选中。

简而言之,这似乎是在您的选项卡的选择事件中处理的。 我的回答可能会或可能不会提出您会接受的解决方案,因为我们没有所有详细信息,例如您使用的是哪个组件ui,我只能提供一个伪解决方案:

在导航选项卡的 ui 逻辑所在的组件内:

onTabSelected(selectedIndex) {
    if (..your logic here) {
        loadIframe(selectedIndex);
        highlightTab(selectedIndex);
    }
}

没有像以前的beforeUnload这样的事件。两个应用程序,即主机和子应用程序可以通过 postMessage 进行通信。因此在 beforeUnload 事件中,您可以向子应用程序发送 postMessage 以突出显示现有选项卡。例如:- 假设您在变量名称 child1.

中引用了 child window
  child1.postMessage('{'tabId': 'tab1'}');

您的子应用程序可以接收此消息并突出显示标识符为 tab1 的选项卡。

也许我们可以使用 window.top 对象创建一个通信系统,例如,假设您在子应用程序中分配了一些 ID。

然后在托管其他应用程序的主应用程序中为 window.top.appsMap = {};

创建一个子对象

然后从每个子应用更新一个布尔值,例如

window.top.appsMap['applicationId'] = hasChangesOrNot

然后从您更改标签页的顶部应用程序,您可以检查当前打开的标签页应用程序 ID 是否有变化,而不是切换标签页,而只是尝试卸载当前的 iframe,这不是最好的解决方案,但如果应该工作你也许还可以向后设置一些通信通道,这将从托管其他应用程序的主应用程序触发,从子应用程序保存

在子应用程序中

const origin = this.getCurrentHostOrigin();
if (cancelSwitchTab) {
    window.parent.postMessage({}, origin); 
}

在主机应用中:

this.renderer.listen(this.windowsRef.nativeWindow, 'message', event => {
  const message = event.data;
  *** your logic to revert highlight to current tab ***
});