title: Trouble with dynamically loading controllers and views with AngularJS/$controllerProvier and RequireJS
body: <p>I cam across this <a href="http://weblogs.asp.net/dwahlin/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs" rel="nofollow">blog posting</a> from Dan Wahlin about dynamically loading controllers and views. I downloaded the source from <a href="https://github.com/DanWahlin/CustomerManager" rel="nofollow">github</a> and tried to reproduce the project on a smaller scale to understand how it all worked. I can get the project to load with the views but where I am stuck is on figuring out why the controller does not seem to bind to the view. Stepping through the code I can see the controller being initialized and injected into the app:</p>
  
  <p>here you can see the app initialize and routes are established</p>
  
  <pre><code>'use strict';
  
  define(['services/routeResolver'], function () {
  
      var app = angular.module('myApp', ['ngRoute', 'ngAnimate', 'ui.bootstrap', 'breeze.angular', 'routeResolverServices']);
  
      app.config(['$routeProvider', 'routeResolverProvider', '$controllerProvider',
                  '$compileProvider', '$filterProvider', '$provide', '$httpProvider',
  
       function ($routeProvider, routeResolverProvider, $controllerProvider,
                 $compileProvider, $filterProvider, $provide, $httpProvider) {
  
           app.register = {
               controller: $controllerProvider.register,
               directive: $compileProvider.directive,
               filter: $filterProvider.register,
               factory: $provide.factory,
               service: $provide.service
           };
  
           //From Dan Whalin project comments: route.resolve() now accepts the convention to use (name of controller &amp; view) as well as the 
           //path where the controller or view lives in the controllers or views folder if it's in a sub folder. 
           // first param is the name of the controller, second param is the directory it and the view exist in, third param is the alias (controller as) optional third param is true false for security 
  
           var route = routeResolverProvider.route;
           $routeProvider
           .when('/', route.resolve('main', '', 'vm'))
           .otherwise({ redirectTo: '/' });
       }
      ]);
  
      ////support for lodash
      //   app.factory('_', ['$window', function ($window) {
      //       return $window._;
      //   }]);
  
      // breeze factory manager
         app.factory('entityManagerFactory', ['breeze', emFactory]);
  
         function emFactory(breeze) {
             // Convert properties between server-side PascalCase and client-side camelCase
             breeze.NamingConvention.camelCase.setAsDefault();
  
             // Identify the endpoint for the remote data service
             var serviceRoot = window.location.protocol + '//' + window.location.host + '/';
             var serviceName = serviceRoot + 'breeze/breeze'; // breeze Web API controller
  
             // the "factory" services exposes two members
             var factory = {
                 newManager: function () { return new breeze.EntityManager(serviceName); },
                 serviceName: serviceName
             };
             return factory;
         };
  
         app.service("httpDataLoader", ["$http", function ($http) {
             this.load = function () {
                 return $http();
             }
         }]);
  
      //global filter to allow html to render in the UI and bypass SCE (secure content expression)
      //usage: ng-html-bind="properyExpresson | html"
         app.filter('html', ['$sce', function ($sce) {
             return function (text) {
                 return $sce.trustAsHtml(text);
             }
         }
         ]);
  
      app.run(['breeze', function (breeze) { }]);//currently doing nothing
      return app;
  });
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>A question was asked about the route resolver and how it was supposed to work:
  From Dan Wahlin Bolg:</p>
  
  <p>The routeResolver.js script creates an AngularJS provider. It’s loaded by RequireJS and used in app.js within the config() function to define routes and resolve them dynamically at runtime.</p>
  
  <p>AngularJS already comes with built-in support for loading views dynamically and with a little more work controllers can be loaded dynamically as well. Loading controller scripts can be done by assigning the resolve property mentioned earlier to a function that handles loading the controller. What’s unique about routeResolver is that it doesn’t accept hard-coded paths to the target view or controller. Instead, you define a base name such as “main” and the resolver will generate the path to the appropriate view and controller based on a standard convention.</p>
  
  <p>within main.js I define the files to load with require</p>
  
  <pre><code>requirejs.config({
      baseUrl: 'app',
      urlArgs: 'v=1.0',
  });
  
  require([
      'app',
      'services/routeResolver',
      'services/config',
      'services/dataService'
  ],
  function () {
      angular.bootstrap(document, ['myApp']);
  });
  </code></pre>
  
  <p>and within my mainController I setup a basic controller</p>
  
  <pre><code>'use strict';
  define(['app'], function (app) {
  
      var injectParams = ['$window', 'dataService'];
  
      var mainController = function($window, dataService){
  
          var vm = this;
          vm.message = 'we are wired up';
  
          vm.connect = function () {
              alert('hello')
          };
      };
  
      mainController.$inject = injectParams;
      app.register.controller('mainController', mainController);
  });
  </code></pre>
  
  <p>index.html is setup as </p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
      &lt;meta charset="utf-8"&gt;
      &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
      &lt;base href="/"&gt;
      &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
      &lt;link href="Content/bootswatch-slate.css" rel="stylesheet" /&gt;
      &lt;title&gt;&lt;/title&gt;
  &lt;/head&gt;
  &lt;body ng-cloak&gt;
      &lt;div ng-view&gt;&lt;/div&gt;
  
  
      &lt;script src="Scripts/angular.min.js"&gt;&lt;/script&gt;
      &lt;script src="Scripts/angular-route.min.js"&gt;&lt;/script&gt;
      &lt;script src="Scripts/angular-animate.min.js"&gt;&lt;/script&gt;
      &lt;script src="Scripts/angular-sanitize.min.js"&gt;&lt;/script&gt;
      &lt;script src="Scripts/angular-ui/ui-bootstrap.min.js"&gt;&lt;/script&gt;
      &lt;script src="Scripts/breeze.min.js"&gt;&lt;/script&gt;
      &lt;script src="Scripts/breeze.bridge.angular.js"&gt;&lt;/script&gt;
  
      &lt;script src="Scripts/require.js" data-main="Scripts/main"&gt;&lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>and the main view is pretty basic</p>
  
  <pre><code>&lt;div&gt;
      &lt;p&gt;static text&lt;/p&gt;
      &lt;p&gt;{{vm.message}}&lt;/p&gt;
      &lt;button type="button" ng-click="vm.connect()"&gt;click&lt;/button&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>What I am seeing in the project is the page/view load fine and within the dev tools I can see the controller as well as all scripts initialize. However  the scoped items within the controller vm.message or the function call vm.connect are not bound or recognized from the view. Dev Tools show no error in the console and the view with static content renders. I think I may be getting fooled with the scope of the controllers is either getting duplicated or I am somehow not injecting it correctly. I tried to use the Angular extension to observe the scope and watches but it would error out. I got the same error when I ran the source project from gitHub, but with the angular extension turned off the source project runs fine. </p>
  
  <p>I tried to setup a plnkr but due to the configuration/routing of the project it wouldn't run so <a href="https://drive.google.com/open?id=0Bw8bzjasfHFNOGJOZjkxdG4tNGs" rel="nofollow">here is a link to the full solution</a> from VS. The code is on a GoogleDrive share if I need to move it to another repository please let me know. I would appreciate any code review and suggestion on what I have missed or overlooked. In comparing my code to what is in Dan's solution it appears to be the same.</p>
  
  <p>I'd appreciate any suggestions or ideas</p>
  
  <p>thanks</p>