这可能以前已经回答过,但是我已经尝试了48个小时,现在很幸运地找到了答案。发布此消息是不得已的方法。
所以我有这个俄罗斯方块克隆,它的工作原理如下:http://www.crawfordcomputing.com/portfolio/Jetris.php
但这在此单页角度应用程序中不起作用:
http://www.crawfordcomputing.com/AkadineWebOS/
我将整个网站重新编码为AngularJS单页应用程序。为此,我通过ng-bind-html加载了html并在此处找到了compile指令:AngularJS directive in ng-bind-html。
我绑定的html字符串正好是:编辑:尝试将canvas作为子节点,没有用。<div><canvas id='gamewindow' width='780px' height='560px'></canvas></div>
必要的脚本通过以下功能加载:Single page application - load js file dynamically based on partial view
注意:html5jetris.js实际上是一个对象:var jetris = { startgame: function(), ...};
使用Firebug,我可以看到DOM中所有添加的元素和脚本。我还假设是已加载的单个页面,所以在结束“;”后不能使用window.onload = jetris.startGame;
。的var jetris = {};
1)我尝试将alert("hello");
作为倒数第二行(恰好在调用startGame之前),并尝试逐步使用firebug。似乎html5jetris.js加载后未运行。
2)我试图直接通过javascript:getElementByID("gamewindow").innerHTML = "hello";
从地址栏中按ID访问画布
没有成功;这是在ng-bind-html执行了1-1.5秒之后几秒钟之后,它才需要角度加载。
3)如果我先抢占地将所有js加载到index.php中,则Firefox将逐步执行它。但是我只想在需要时加载javascript。这不能解决无法通过ID访问画布的问题。
4)Jetris本身就可以工作,只是AngularJS不动态加载。
注意:Jetris不需要jQuery,即使它已用于Angular。它取决于我自己的utitlty.js(作为javascript类的一部分制作,转换为对象:var U = {};
)和我自己的html5canvas.js(再次为var canvas = {};
),因为它们是对象,所以它们中的变量不应颠簸带有jQuery或Angular的头。
有任何想法吗?
这是指令:
.directive('compile', ['$compile', function ($compile) {
return function(scope, element, attrs) { //taken from Joël (Thank you!) source: https://stackoverflow.com/questions/26594153/angularjs-directive-in-ng-bind-html
scope.$watch(
function(scope) {
// watch the 'compile' expression for changes
return scope.$eval(attrs.compile);
},
function(value) {
// when the 'compile' expression changes
// assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current
// scope.
// NOTE: we only compile .childNodes so that
// we don't get into infinite loop compiling ourselves
$compile(element.contents())(scope);
}
);
};
}])
Jetris.php:
<?php //Jon Crawford AkadineWebOS pages/jetris.php
//describe window
$window = array();
$window['content'] = "<canvas id='gamewindow' width='780px' height='560px'></canvas>";
$window['title'] = "Jetris";
$window['x'] = 20;
$window['y'] = 250;
$window['id'] = 900;
$window['requireJS'] = array();
$window['requireJS'][0] = "scripts/html5Jetris.js";
$window['requireJS'][1] = "scripts/html5Canvas.js";
$window['requireJS'][2] = "scripts/utilities.js";
echo json_encode($window);
?>
这将被加载到具有标题栏和可拖动退出按钮的div中。我的菜单系统就像图标一样。我的AkadineWebOS看起来像普通的桌面。我有一个about.php和welcome.php,它们在div窗口中都能正常工作。
最佳答案
好的,所以这是特例,我可能没有澄清我的问题。这是我用来实现目标的步骤。
要将HTML格式的字符串加载到DOM,我使用了Joël的$ compile指令(谢谢!)来源:AngularJS directive in ng-bind-html
要加载外部依赖项脚本文件,我使用了Ben Thielker的加载脚本函数(谢谢!)来源:Single page application - load js file dynamically based on partial view
然后,将Java游戏Jetris中的onload更改为:var externalJS = { run: function() { window.jetris.startGame(); } };
这样,无论何时我想添加新游戏或其他javascript应用程序,我都不必重新编码我的角度应用程序,这使我的应用程序可以检查var externalJS是否未定义,如果已定义,则它执行externalJS.run() ;。如果应用程序的div窗口已关闭,则重新打开后将有效地重新启动它。
现在,由于所有内容都是使用Angular的HTTP模块加载的,因此您必须等待Angulars承诺完成所有内容的加载。如果尝试尽快运行它,则会出现空白窗口且没有游戏。为此,我使用
setTimeout(function() {
if (typeof externalJS != 'undefined'){
externalJS.run();
}},750);
在HTTP模块的successCallback中给它一些时间。
这是该项目的Alpha的链接,这里解决了所有问题。您可以拖动窗口和图标,像普通桌面一样打开同一窗口中的多个窗口,除非像Jetris一样设置了oneInstance标志,并且您可以玩Jetris!看看这个! AkadineWebOS
特里瓦(Triva):我用一个在线句柄创建了Akadine的首字母缩写词,它是一个程序,该程序在几年前就使随机可读的单词(不是真实的,只是可读的)出现了,直到最近才出现在Advanced Kiosk和Dynamic Internet Navigation Environment中。