I have a very simple AngularJS SPA, using UI Router to switch between two views. Upon clicking on the Home link, the user will see a line of text. The About link should do the same, but its routing is configured to use a templateUrl instead of a template string:
$stateProvider
.state("home", {
url: "/home",
template: "<h3>This is the Home content</h3>"
})
.state("about", {
url: "/about",
templateUrl: "about.html",
controller: "aboutController"
});
about.html is about as simple as it can be:
<!DOCTYPE HTML>
<html ng-app="simpleApp">
<head>
<title>About</title>
<script src="aboutcontroller.js"></script>
</head>
<body ng-controller="aboutController">
<h3>{{message}}</h3>
</body>
</html>
... and its controller is also plain contrived boilerplate:
console.log("Registered aboutController"); ///////////
angular.module("simpleApp")
.controller("aboutController", ["$scope", function ($scope) {
console.log("Created aboutController"); ///////////
$scope.message = "This is the About content!";
}]);
Note the two console statements that helped me diagnose the problem.
The problem: While the controller script file executes, the controller itself is never called. So instead of seeing the text, the user just sees:
{{message}}
This seems to be related to the fact that I include the script file in the template file (about.html). If I move the script tag to index.html, the problem goes away and everything works as expected.
Here's a plunker that shows my problem and workaround.
The Real Problem: In this very simple and contrived example, it's reasonable to include all the controller scripts in the main page of the SPA. But for even a very simple web application, there may be dozens of pages with dozens of controllers. Adding all the controllers to the main page won't scale well for performance and won't scale well for maintenance.
So what is the appropriate way of setting this up? How/where should the controller script be included?
Edit: I forgot to mention the error I receive (yes, I know). With the script tag in about.html, I receive a message saying
Argument 'aboutController' is not a function, got undefined
This happens directly after the console message "Registered aboutController". If I move the script tag to include the controller in index.html instead, no error is shown. Again, to me this indicates that the controller is simply not available in time to call. Moved to index.html, it is fully registered by the time it is needed.
{{message}}
on the page, that means the template hasn't been processed at all. If Angular did process the template, you'd simply see nothing ifmessage
wasn't populated. That points to something producing a fatal error. Have you checked your Javascript console for errors?ng-controller
in the file, since you're already usingcontroller: ...
in the router. You must include the file with the controller into your main file, as a dependency of your mainmodule
, otherwise the router can't find the controller when trying to load your route.