4

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

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

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

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

4

4 回答 4

5

我的理解是你必须更新一个现有的项目,该项目的构建方式beforeunload是使用事件来实现类似于 Angular 特性的路由保护。beforeunload根据在事件的帮助下实现的逻辑,您是否加载选定的 iframe 。您似乎不赞成更改此实现,这就是为什么寻求一种解决方案来满足您的要求,应用类似的方法,如另一个窗口事件。

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

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

在导航选项卡的 ui 逻辑发生的组件内部:

onTabSelected(selectedIndex) {
    if (..your logic here) {
        loadIframe(selectedIndex);
        highlightTab(selectedIndex);
    }
}
于 2020-06-05T23:51:11.037 回答
4

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

  child1.postMessage('{'tabId': 'tab1'}');

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

于 2020-06-09T12:32:31.210 回答
1

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

然后在托管其他人的主应用程序中,您创建一个子对象window.top.appsMap = {};

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

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

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

于 2020-06-11T06:22:57.897 回答
-1

在子应用程序中

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 ***
});
于 2020-06-12T00:47:20.153 回答