这可能以前已经回答过,但是我已经尝试了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中。

07-24 15:02