I'm trying to learn AngularJS' view and routing mechanism, following AngularJS' own tutorial.
My problem is the tutorial is declaring all its controllers in the global scope, and I belive this is a bad practice because we're polluting it as we add more controllers.
This is a quick working page I've been able to build following the aforementioned tutorial (there's a fiddle, too):
<!doctype html>
<html>
<head>
<title>Test</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.1/angular.js"></script>
<script>
"use strict";
var MyFirstController = function ($scope) {
// Do something here.
};
var MySecondController = function ($scope) {
// Do something here.
};
var myModule = angular.module("MyModule", []);
myModule.config(["$routeProvider", function ($routeProvider) {
$routeProvider.when("/first-page", {
template: "<p>My first controller.</p>",
controller: MyFirstController
});
$routeProvider.when("/second-page", {
template: "<p>My second controller.</p>",
controller: MySecondController
});
}]);
$(document).ready(function () {
angular.bootstrap(document, ["MyModule"]);
});
</script>
</head>
<body>
<h1>Test</h1>
<div data-ng-view></div>
<p><a href="#/first-page">Click me!</a></p>
<p><a href="#/second-page">Click me too!</a></p>
</body>
</html>
Being naïve, I tried to move the controllers inside the module:
myModule.config(["$routeProvider", function ($routeProvider) {
$routeProvider.when("/first-page", {
template: "<p>My first controller.</p>",
controller: MyFirstController
});
$routeProvider.when("/second-page", {
template: "<p>My second controller.</p>",
controller: MySecondController
});
}]);
myModule.controller("MyFirstController", ["$scope", function ($scope) {
// Do something here.
}]);
myModule.controller("MySecondController", ["$scope", function ($scope) {
// Do something here.
}]);
Alas, it doesn't (obviously) work, throwing a ReferenceError: MyFirstController is not defined exception.
How can I have an AngularJS module use its own controllers in its own routes configuration?
Once you know the solution, it's really simple: just specify the controller as strings instead of objects:
myModule.config(["$routeProvider", function ($routeProvider) {
$routeProvider.when("/first-page", {
template: "<p>My first controller.</p>",
controller: "MyFirstController"
});
$routeProvider.when("/second-page", {
template: "<p>My second controller.</p>",
controller: "MySecondController"
});
}]);
This way AngularJS will resolve the controller name to the one you've defined inside the module.
And it's minification safe too!
I've created a fiddle demonstrating it.