window.postMessage ()および window.on("message") システムを使用して、2 つのアプリケーションを接続します。
たとえば、コレクションのウィジェットを表示できる ember アプリが iFrame にあり、メイン アプリに ID セレクターがあるとします。これがどのように機能するかを次に示します。
メインアプリで:
App.IndexController = Ember.Controller.extend({
//... other stuff
actions: {
showWidget: function () {
var id = parseInt(this.get("widgetId"), 10),
iframe = $("#inner_page")[0];
iframe.contentWindow.postMessage(
JSON.stringify({ type: "action", args: ["showWidget", id]}),
"*");
}
}
});
widgetId
iframe に渡す ID です (たとえば、テキスト フィールドに関連付けることができます)。iframe の ID は「inner_page」になります。呼び出しの 2 番目の引数postMessage
は origin です。通信が機能するようになったら、それを保護することを検討する必要があります。
iframe アプリのコードはさらに興味深いものです。
$(window).on("message", function(e) {
var message = JSON.parse(e.originalEvent.data),
handler = App.messageHandlers[message.type];
if (!handler) {
consolw.log("WARNING! Invalid action call!");
return;
}
handler(message);
});
App.messageHandlers = {
action: function (msg) {
if (App.activeController) {
App.activeController.send.apply(App.activeController, msg.args);
}
}
};
App.IndexRoute = Ember.Route.extend({
//...
setupController: function (controller, model) {
this._super(controller, model);
App.activeController = controller;
}
});
App.IndexController = Ember.Controller.extend({
//...
actions: {
showWidget: function (id) {
// update active widget, load route or whatever
}
}
});
いくつかのメモ:
メッセージには固定の「タイプ」プロパティがあります。現在、これは常に「アクション」ですが、複数の通信プロトコルが必要な場合に役立つ可能性があります。
メッセージの送信先となるアクティブなコントローラーまたはルートを取得するには、何らかの方法が必要です。この例では、新しいコントローラーがセットアップされるたびに、アクティブなコントローラーをキャッシュしています ( App.activeController
)。このモデルを使用した場合、これはおそらく Route Mixin として実装する必要があります。これがより大きなアプリケーションでどれだけうまく機能するかはわかりませんが、この例では十分です。