2017-01-16 62 views
3

我有多个Angular 2应用程序,它们应该由门户应用程序(也称为Angular 2)提供服务。所以门户应用程序有一个标题区域,其中包含指向所有底层应用程序当用户点击一个应用程序链接时,对应的角度2应用程序将加载到门户主体的iframe中。在我当前的项目中使用角度2的iframe来进行父项通信

enter image description here

现在我开发一个中央授权服务。在门户中,我有一个服务,它拥有当前登录用户的权限。我的问题是:是否有可能在各个应用程序(iframe)中访问父(门户)的角度2服务/组件?这似乎是possbile在角1 via scope

回答

2

我期待在使用这样的时刻类似的东西(在iframe与子应用门户应用程序) 您可以在服务器和客户机之间的通信(在任一方向) window.postMessage发送数据。

因此,例如在服务器上的应用程序:

var iframe = document.getElementById('useriframe'); 
    if (iframe == null) return; 
    var iWindow = (<HTMLIFrameElement>iframe).contentWindow; 

    iWindow.postMessage({"for":"user","data":"anything"}, 'http://localhost:4001'); 

,并在客户端应用程序(内嵌框架内举行)

export class AppComponent { 

@HostListener('window:message',['$event']) 
onMessage(e) 
{ 
if (e.origin!="http://localhost:4200") 
    { 
    return false; 
    } 
if (e.data.for=="user") 
    { 
    alert('here i am'); 
    } 
} 

显示子帧路线父 所以,我的实现将令牌和用户信息从shell应用程序传递给子iFrame,并将路由信息从子应用程序传递回shell,以便url反映在第儿童申请。 在孩子应用程序,你可能会有这样的路线:

[userapp]/edituser /用户名

,我们希望将其发布到父应用程序,并显示类似的路线:

http://mywebsite/main/application/user#edituser/bob

注意,我们使用#标签来标记一个孩子的路线,和在你的孩子,你的应用程序每一个拦截导航事件,并通过

export class MyRoutingComponent implements OnInit { 
constructor(private router: Router) { 
router.events.subscribe((event: Event)=>{ 
    if (event instanceof NavigationEnd){ 
     let url=(<NavigationEnd>event).url; 
     if (url.length>1)//don't post message about base route '/' 
      window.parent.postMessage({"for":"dashboard", "operation":"changeroute","route":url},'*') 
    } 

}) 
} 

发布新的路线,然后在父应用解析消息,并用它来更新显示的位置路径。

url = url +'#' + route;    
    this.location.go(url); 
2

您真的很感谢@ jazza1000给出的解决方案,它帮了我很大的忙。

我们的问题是在角度cli的当前(迄今)版本中有一个bug,即使使用allowJs也可以阻止使用外部JS文件。我们将使用jsplumb(外部js)来表示一些流程图。 (Actual issue on stack overflow

所以我们决定去与托管在附加角4应用程序使用外部JS功能的方法。父角度5应用程序将带有iFrame的角度4应用程序。因此,当用户想要查看流程图时,我们将在iframe中打开angular4应用程序,然后一旦完成,他将点击保存在角度4应用程序中,保存所有修改,然后将消息发送到父窗口,关闭/隐藏div与iframe。

我们在角5父应用程序具有代码

@HostListener('window:message', ['$event']) 
    onMessage(e) { 
    debugger; 
    if (e.origin != "http://localhost:4201") { 
     return false; 
    } 
    if (e.data.for == "user") { 
     alert('here i am'); 
    } 
    } 

我们的iFrame角4上保存按钮的应用程序具有代码(我们开始与--port 4201应用)

window.parent.window.postMessage({"for":"user","data":"anything"}, 'http://localhost:4200')