【发布时间】:2014-07-28 02:22:12
【问题描述】:
有没有人有一个工作示例来说明如何以角度发送和接收 window.postMessage() 调用?我在 github 和 ngmodules 上找到了 ng-post-message 模块,但我查看了该代码,它对我来说没有多大意义,并且文档缺少一个工作示例。
编辑:添加我失败的尝试
景色
<div simulation-host element="thing in things"></div>
</div>
<div id="debugConsole">
<h1>MESSAGE CONSOLE</h1>
<p id="debugText"></p>
</div>
型号
$scope.things =
[
{
"location" : "Foobar",
"resource" : $sce.trustAsResourceUrl("http://external.domain:14168/Foo/Bar"),
"title" : "Launch"
}
];
我对指令的尝试
var simulationFrameHost = angular.module('proxy.directives', []);
simulationFrameHost.config(function ($sceDelegateProvider){
//URL Regex provided by Microsoft Patterns & Practices.
$sceDelegateProvider.resourceUrlWhitelist(['^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$','self']);
});
simulationFrameHost.directive('simulationHost', ['$window',function($window) {
return {
retrict: 'ACE',
transclude: 'element',
replace: true,
scope: true,
template: [
'<ul>',
'<li>',
'<span>',
'<a href="#">',
'{{thing.location}}',
'</a>',
'</span>',
'<messenger>',
'<iframe ng-src="{{thing.resource}}" />',
'</messenger>',
'</li>',
'</ul>'
].join(''),
compile: function (tElement, tAttrs, transclude) {
var interval;
var show = function(msg)
{
var debugText = document.getElementById("debugText");
if(debugText){
debugText.innerHTML += msg + "<br/>";
}
};
var rpt = document.createAttribute('ng-repeat');
rpt.value = tAttrs.element;
console.log(tAttrs.element);
tElement[0].children[0].attributes.setNamedItem(rpt);
$(tElement[0].children[0].children[0].children[0]).on("click", function(event){
console.log(event);
var iframe = tElement[0].children[0].children[1].children[0].contentWindow;
show("Initiating connection with: " + event.currentTarget.host);
var message = {
action: 'syn',
param: 'connection'
};
interval = setInterval(function(){
//*****************************************
iframe.postMessage(JSON.stringify(message), 'http://'+ event.currentTarget.host);
//*****************************************
}, 500);
return false;
});
}
}
}]);
我正在尝试适应 Angular 的工作遗留代码
请注意,此代码使用弹出窗口而不是 iframe;遇到了IE在windows之间的postMessage被破坏所以不得不回退到iframe的复杂情况。
标记
<body>
<div id="debugConsole">
<h1>MESSAGE CONSOLE</h1>
<p id="debugText"></p>
</div>
<h1>This is a test</h1>
<ul>
<li>
<a href= "http://external.domain:14168/Foo/Bar" target="_blank" ><p>Foobar</p></a>
</li>
</ul>
<script src="js/jquery-1.10.2.min.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-animate/angular-animate.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="js/SCORM_API_wrapper.js"></script>
<script src="js/json2.js"></script>
<script src="js/plugins.js"></script>
<script src="js/index.js"></script>
</body>
index.js
$('a').on("click",function(event){
console.log(event);
var pop = window.open(event.currentTarget.href, 'poop');
show("Initiating connection with: " + event.currentTarget.host);
var message = {
action: 'syn',
param: 'connection',
};
interval = setInterval(function(){
pop.postMessage(JSON.stringify(message), 'http://'+ event.currentTarget.host);
}, 500);
return false;
});
$(window).on("message", function(e) {
clearInterval(interval);
var eventData = JSON.parse(e.originalEvent.data);
show("Message received from: " + e.originalEvent.origin);
if(eventData.action) {
switch (eventData.action) {
case 'syn-ack':
ack(e.originalEvent, eventData.param, eventData.value);
break;
case "set":
show("Set request received: " + e.originalEvent.data);
set(eventData.param, eventData.value);
break;
case "get":
show("Get request received: " + e.originalEvent.data);
var value = get(eventData.param);
var response = {
action: "response",
type: "get",
param: eventData.param,
value: value
};
e.originalEvent.source.postMessage(JSON.stringify(response), channel);
break;
}
}
});
在我的指令编译中,我试图将点击事件连接到生成的锚标记。我试图点击向 iframe 发布消息,但 iframe.postMessage 什么也没做。它刚刚进入下界,我从今天早上 10 点开始就一直在研究这个。我的眼睛开始发呆:p
编辑:为单独容器之间的通用消息传递指令添加扩展要求(现在我有功能代码),无论容器类型如何:
1)iframe to parent
2)window to window(
我有遗留代码工作,通过生成窗口来执行窗口到窗口消息传递 第二个在创建后立即向其发布“syn”消息。然后第二个窗口将消息作为“syn”接收,并将发送者存储为 messageHandle,以便它可以维护一个通道来发布返回消息,然后返回“syn-ack”。发起者随后发出“ack”,辅助窗口收到 ack 并继续其工作。 (如果 ack 在超时之前没有返回,我记录了连接失败,然后辅助窗口轮询一段时间以尝试恢复连接)
【问题讨论】:
-
您能否发布您尝试过的代码示例,或者您尝试在 Angular 中模拟的等效纯 js 代码?
-
很难重构我当前的代码以仅隔离发布消息的尝试。不过我可以试试。
-
我作弊了。 $(window).on("消息",function(){});在控制器中。我花了太多时间试图让它以“角度方式”工作。花了大约 10 分钟让它以“实用的方式”工作。有时间我会重构。
-
实用作品。来吧,把它作为你的答案发布。
标签: angularjs postmessage