load angular modules after bootstrap

by josketres

HTML

<div ng-app="testApp">
  <div ng-controller="testCtrl">
    <button ng-click="registerNewModuleAndCompile()">Register new module with a controller</button>
  </div>
</div>

<h3>Debug</h3>
<ul id="debug">
</ul>

SCSS

button {
    display: block;
    margin: 8px;
    padding: 8px;
}

JavaScript

var app = angular.module('testApp', []);

app.controller('testCtrl', function($scope, $compile, $rootScope) {
  // register a new module, add an element with a newCtrl and compile it
  $scope.registerNewModuleAndCompile = function() {
    var newDiv = document.createElement('div');
    newDiv.setAttribute('ng-controller', 'newCtrl');
    newDiv.innerHTML = '{{message}}';
    document.querySelector('[ng-app]').appendChild(newDiv);
    registerNewModuleAfterBootstrap();
    $compile(newDiv)($rootScope.$new());
  };

});

// Hack to load controllers after bootstrap.
// see http://www.bennadel.com/blog/2553-loading-angularjs-components-after-your-application-has-been-bootstrapped.htm
app.config(function($controllerProvider) {
  app._controller = app.controller;
  app.controller = function(name, constructor) {
    $controllerProvider.register(name, constructor);
    return app;
  };
});

// Hack to load modules after bootstrap.
// see: http://pinkieguy.com/post/101949656975/loading-module-dependencies-in-angular-after
angular.module = function() {
  return app;
};

// allow run blocks for lazy loaded modules
app.run(function($injector) {
  app._run = app.run;
  app.run = function runAfterBootstrap() {
    $injector.invoke(arguments[0]);
  };
  return app;
});

app.run(function() {
  log('running in a run() block before bootstrap');
});

// registers a new angular module call myNewModule (will be called after bootstrap)
function registerNewModuleAfterBootstrap() {
  angular.module('myNewModule', [])
    .controller('newCtrl', function($scope) {
      $scope.message = 'hello from my new module after bootstrap';
    }).run(function() {
      log('running in a run() block after bootstrap');
    });
}

function log(message) {
  var entry = document.createElement('li');
  entry.textContent = message;
  document.getElementById('debug').appendChild(entry);
}