Script to load controllers dynamically for AngularJS
Feedback

This is an interesting way of loading controllers. I like the application of the promises. It does feel a little weird not to have an ng-app directive but it makes sense given the nature of your code.

Suggestions

The suggestions below can simplify the code, but may not necessarily be optimal or have desired browser support.

Iterating functionally

One could utilize a functional approach instead of the declarative for loop:


for(var i = 0;i &lt; ngControllers.length;i++)



Because each iteration pushes a promise into the array promises, that loop can be replaced by a call to Array.map():

var promises = Array.prototype.map.call(ngControllers, function(ngController) 


Or .map could be called on an array after converting the nodeList to an array via Array.from() (but beware of Browser compatibilty on that)

var promises = Array.from(ngControllers).map(function(ngController)


Or for a completely es-6 approach, use the spread operator:    

var promises = [...ngControllers].map(function(ngController)


At the end of each iteration, simply return the promise instead of pushing it into the array. 

    // Push promises to array to resolve them all together later on
    return promise;//promises.push(promise);
}); //end the call to .map()


Bear in mind that the functional approach would likely be somewhat slower because a function call is added for each iteration, but for a small number of controllers this should be a negligible difference. If you would like to become more familiar with functional JavaScript, I recommend these exercises.

Use partial(-ly applied) functions for callbacks

Instead of making a closure just to call resolve():


script.addEventListener('load', function() {
    resolve(script);
});



Use Function.bind() (different than (angular.bind()) to create a partially applied function for each time resolve() is called. 

script.addEventListener('load', resolve.bind(null, script));


Bear in mind that the event listener would pass an event argument to the callback, but that should be the second argument when script is bound as the first argument.   

The same is true for calling the bootstrap function after all promises have been resolved:


Promise.all(promises).then(function() {       
    angular.bootstrap(document, ['app']);
});



Can be simplified like below:

Promise.all(promises).then(angular.bootstrap.bind(null, document, ['app']));


Use addEventListener instead of onload

This likely wouldn't be an issue in a small application but in case there was other code (potentially multiple functions) that needed to be executed when the page is loaded, it might be simpler just to use window.addEventListener('DOMContentLoaded', function() {...}) instead of window.onload = function() {...};