web-dev-qa-db-ja.com

Angular 2 iframeから親への通信

私の現在のプロジェクトでは、複数のAngular 2つのアプリケーションがあり、これらはポータルアプリケーションによって提供される必要があります(また、Angular 2)。ユーザーが1つのアプリリンクをクリックすると、対応するangular 2アプリがポータル本体のiframeに読み込まれます。

enter image description here

次に、中央認証サービスを開発します。ポータルには、現在ログインしているユーザーの権限を保持するサービスがあります。私の質問は:angular 2つのサービス/個々のアプリ(iframe)内の親(ポータル)のコンポーネントにアクセスすることは可能ですか?angular 1 スコープ経由

16
JuHarm89

私は現時点で似たようなことをしています(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');

クライアントアプリケーション(iFrame内でホスト)

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');
  }
}

親での子フレームルートの表示したがって、私の実装では、トークンとユーザー情報をシェルアプリケーションから子iFrameに渡し、ルーティング情報を渡しますURLが子アプリケーションで選択されたルートを反映するように、子アプリケーションからシェルに戻ります。子アプリケーションでは、次のようなルートがあります。

[userapp]/edituser/username

、それを親アプリケーションに投稿し、次のようなルートを表示したいと思います。

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);
11
jazza1000

こんにちは、@ jazza1000が提供してくれたソリューションに本当に感謝しています。

私たちの問題はangular cliの現在の(現在の)バージョンにあり、allowJsを使用しても外部JSファイルの使用を妨げる bug があります。一部のフローチャートを表すjsplumb(外部js)( スタックオーバーフローの実際の問題

そこで、追加のangular 4アプリケーションで外部JSを使用する機能をホストするアプローチを採用することにしました。そして、親angular 5アプリケーションはangular 4アプリケーションとiFrame。したがって、ユーザーがフローチャートを表示したい場合、iframeでangle4アプリケーションを開き、完了したらangular 4すべての変更を保存し、iframeでdivを閉じる/隠す親ウィンドウにメッセージを送信するアプリケーション。

angular 5の親アプリケーションにはコードがあります

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

IFrame angular 4保存ボタンのアプリケーションにはコードがあります(アプリケーションを--port 4201で起動しています)

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