1

This probably has been answered before but I have tried for 48 hours now to find an answer with now luck. Posting this is a last resort.

So I have this Tetris clone and it works as seen here: http://www.crawfordcomputing.com/portfolio/Jetris.php

But it does not work in this single page angular app:

http://www.crawfordcomputing.com/AkadineWebOS/

I am re-coding the whole site to be a AngularJS single page app. To this end, I load the html via ng-bind-html and the compile directive found here: AngularJS directive in ng-bind-html.

The html string I am binding is exactly: EDIT: tried making canvas a childnode, did not work.<div><canvas id='gamewindow' width='780px' height='560px'></canvas></div>

The necessary scripts are loaded via the function found here: Single page application - load js file dynamically based on partial view

Note: html5jetris.js is actually an object: var jetris = { startgame: function(), ...};

Using firebug, I can see all added elements and the scripts in the DOM. I also am assuming that being a single page already loaded that I cannot use window.onload = jetris.startGame; after the closing ";" of var jetris = {};

1) I tried putting an alert("hello"); as second to last line (just before the call to startGame) and tried stepping through with firebug. It appears that html5jetris.js, while loaded, is not running.

2) I tried to access the canvas by id directly from address bar with javascript:getElementByID("gamewindow").innerHTML = "hello"; no success; this was several seconds after the ng-bind-html executed well past the 1-1.5 seconds it takes angular to load it.

3) if I pre-emptivly load all the js in my index.php, then firefox will step through it. But I only want to load the javascript when needed. This does not fix not being able to access the canvas by id.

4) by it self, Jetris works, just not loaded dynamically by AngularJS.

Note: Jetris does not require jQuery, even though it's there for Angular. It depends on my own utitlty.js (made as part of a javascript class, converted to object: var U = {};) and my own html5canvas.js (again, var canvas = {};) Since these are objects, the variables in them should not bump heads with anything jQuery or Angular.

Any ideas?

here is the directive:

.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);
?>

This gets loaded to a div with title bar and exit button that is draggable. My menu system is icon like. My AkadineWebOS looks like a regular desktop. I have an about.php and a welcome.php that work just fine in my div-windows.

Community
  • 1
  • 1
Jon Crawford
  • 193
  • 11
  • You can create a directive to handle the loading and such. The directive construtor allows you access to the element, with which you can find the elements for your script to use – MiltoxBeyond May 29 '16 at 22:35
  • I have added the directive that I use to load HTML. I use this to load all my content to a div. I have also added my jetris.php so you can see how I send the data. This is very dynamic, but I guess in the content object that I set up I can add a variable that I can use to specify a specific directive. I'm considering uploading what I have to my website so you can see the gist of it. – Jon Crawford May 29 '16 at 22:45
  • Also, I'm trying to make this highly customizable, and ultimately to be used by others who aren't so coding savvy. So in the end I want to be able to add new pages via a database and admin login. Code will be uploaded, like jsfiddle, and apps made, by never dropping to the website code. So having to add one off's to the directive won't be ideal. I have uploaded what I got to my host to link to but they are having issues with PDO, and I do not want to go backwards by re-coding it to mySQLi. Sorry you will have to wait a bit for that link. – Jon Crawford May 30 '16 at 02:19

1 Answers1

0

Ok so this is a special case I probably did not clarify my question. Here are the steps I used to accomplish my goal.

To load an HTML formated string to the DOM I used a $compile directive by Joël (Thank you!) source: AngularJS directive in ng-bind-html

To load external dependency script files, I used a load script function by Ben Thielker (Thank you!) source: Single page application - load js file dynamically based on partial view

Then I change the onload in my java game Jetris to: var externalJS = { run: function() { window.jetris.startGame(); } };

So that I will not have to re-code my angular app whenever I want to add a new game or other javascript app, this allows my app to check if var externalJS is undefined and if is is defined, it executes externalJS.run();. If the app's div-window is closed, this will effectively restart it when reopened.

Now since everything is loaded using Angular's HTTP module, you have to wait for Angulars promise to finish for everything to be loaded. If I try to run it to soon, I get a blank window and no game. To that end, I use

setTimeout(function() {
if (typeof externalJS != 'undefined'){
    externalJS.run();
}},750);

in the HTTP module's successCallback to give it some time.

Here is a link to a working Alpha of the project, with all issues questioned here ironed out. You can drag the windows and icons, open more than one of the same window like a normal desktop unless a oneInstance flag is set like with Jetris, and you can play Jetris! Check it out! AkadineWebOS

Triva: I created the acronym Akadine as a online handle with a program that made random readable words (not real, just readable) years ago, and came up only recently with Advanced Kiosk And Dynamic Internet Navigation Environment.

Community
  • 1
  • 1
Jon Crawford
  • 193
  • 11