0

We are currently looking into AngularJS for a kids application for iPad using Phonegap. There are activities and small games build with CreateJS. We want to include these games or activities dynamically when the user selects them in the menu. How would I load the game related JS files in the angular template? Does ng-include help here?

1
  • idk why this was downvoted. I can't sniff anything wrong with this question. Commented Jul 28, 2015 at 3:15

2 Answers 2

2

My first instinct would be to suggest ng-view and create routes with $routeProvider for the various games you have in mind. Here's a quick snippet adapted from the angular docs (v1.1.5):

angular.module('ngView', [], function($routeProvider, $locationProvider) {
  $routeProvider.when('/Game1', {
    templateUrl: 'Game1.html',
    controller: Game1Cntl,
    controllerAs: 'game1'
  });
  $routeProvider.when('/Game2', {
    templateUrl: 'Game2.html',
    controller: Game2Cntl,
    controllerAs: 'game2'
  });

  // configure html5 to get links working on jsfiddle
  $locationProvider.html5Mode(true);
});

While the content specified by templateUrl will be loaded on demand, this still assumes that your controllers, Game1Cntl and Game2Cntl in this example, are already loaded before the user accesses your menu to change the route in the application.

If you decide you also need to load the controllers themselves on demand, one approach you can take is using the resolve option of the $routeProvider. This is intended to inject values into the controller before the controller is instantiated. However, you can use this to lazy load the controller itself.

$routeProvider.when('/Game1', {
    templateUrl: 'Game1.html',
    controller: Game1Cntl,
    controllerAs: 'game1',
    resolve: {
        dynamicallyLoadedController: functionThatReturnsAPromise
    }
  });

Here functionThatReturnsAPromise could be something like:

function getAController($q) {
    var deferred = $q.defer();

    $.ajax({
       url: '/where/ever/your/controller/script/is.js',
       dataType: "script",
       success: function(script, status, jqXHR) {
         // make your script available to angular
         // angular will find it on the global window object but that's not real tidy          
         deferred.resolve(script); // at this point angular can proceed with the route
       }
     });

    // TODO: you'd want to handle errors and reject the promise here
    // in a real implementation

    return deferred.promise;
}
getAController.$inject = ['$q']; // for when script is minified

Here getAController() is using jQuery to download and execute a dynamically loaded script. It's also being injected with angular's $q to create a promise.

Note that contrary to the intention of the resolve option which is to inject a value in the controller this approach just leverages the fact that we can return a promise which gives us an asynchronous opportunity to lazy load the controller (or potentially other services, directives, etc.). What we resolve the promise with here isn't actually the point in this case. Perhaps there is or will be a more elegant way to tackle this problem in the future.

Sign up to request clarification or add additional context in comments.

2 Comments

+1 for making this answer very complete. However, it would be helpful if the URL could be defined in the routeprovider maps. It isn't very neat to make a function for each controller.
Based on it I created a service, JSLoader. check here github.com/farazshuja/JSLoader
1
var controllerProvider;

var app = angular.module('myApp', []);
app.config(function($controllerProvider) {
  controllerProvider = $controllerProvider; //cache this reference
});

function myCtrl($scope) { //this controller can be loaded by ajax
 //etc
}
//then register it with Angular like this
controllerProvider.register('myCtrl', myCtrl);

Using this logic, you can easily lazy-load controllers and directives into Angular. For much more detail and live demos, see these posts:

Basic demo: Directive for lazyloading data in AngularJS

Real life example (advanced): Lazy loading Angular views and controllers on page scroll

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.