Dave Gordon Dave Gordon - 1 month ago 16
Javascript Question

AngularJs Controller in External file and using route

I have had a look through SO and nothing has helped.

This is my app.js

var app = angular.module("qMainModule", ["ngRoute"])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
templateUrl: 'templates/anonHome/anonHome.html',
controller: 'templates/anonHome/anonHomeController'
})
.when("/about", {
templateUrl: 'templates/anonHome/anonAbout.html',
controller: 'templates/anonHome/anonAboutController'
})
.when("/services", {
templateUrl: 'templates/anonHome/anonServices.html',
controller: '/templates/anonHome/anonServicesController'
})
.when("/contact", {
templateUrl: 'templates/anonHome/anonContact.html',
controller: '/templates/anonHome/anonContactController'
})
.when("/register", {
templateUrl: 'templates/anonHome/anonRegister.html',
controller: '/templates/anonHome/anonRegisterController'
})
.when("/login", {
templateUrl: 'templates/anonHome/anonLogin.html',
controller: '/templates/anonHome/anonLoginController'
})

$locationProvider.html5Mode(true);
})



app.controller("qMainController", function ($scope) {
$scope.Title = " Welcome to Qiao";
$scope.qNavigationTemplatePath = "/templates/topMenu/anonTopNavigation.html";
$scope.copyrightMessage = "Qiao ";
$scope.copyrightYear = new Date();
});


The routing works as expected and the partial templates are being shown but the partial templates controllers are not being recognised as a function.

The Layout Template looks like this

<!DOCTYPE html>
<html ng-app="qMainModule">
<head ng-controller="qMainController">
<base href="/" />
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Qiao :: {{Title}}</title>

<!-- Bootstrap Core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="../css/modern-business.css" rel="stylesheet" />
<!-- Custom Fonts -->
<link href="font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->


<script src="/scripts/angular.js"></script>
<script src="../scripts/angular-route.js"></script>
<script src="/app/app.js"></script>
<script src="templates/anonHome/anonHomeController.js"></script>



<!-- <link href="../styles/qiao.css" rel="stylesheet" /> -->


</head>
<body ng-controller="qMainController">
<div ng-include="qNavigationTemplatePath">

</div>

<!-- Page Content -->
<div class="container">
<ng-view></ng-view>
</div>

<!-- Footer -->
<footer>
<div class="row">
<div class="col-lg-12" ng-controller="qMainController">
Copyright &copy; {{copyrightMessage}} {{copyrightYear | date:'yyyy'}}
</div>
</div>
</footer>

<div >
<!-- jQuery -->
<script src="js/jquery.js"></script>

<!-- Bootstrap Core JavaScript -->
<script src="js/bootstrap.min.js"></script>

<!-- Script to Activate the Carousel -->
<script>
$('.carousel').carousel({
interval: 5000 //changes the speed
})
</script>

</div>
</body>
</html>


The partial template looks like this:

<script src="anonHomeController.js"></script>

<div ng-controller="anonHomeController">

<h1>{{Title}}</h1>

</div>


and its controller is this

function anonHomeController($scope) {
$scope.Title = " Welcome to Qiao";
$scope.qNavigationTemplatePath = "/templates/topMenu/anonTopNavigation.html";
$scope.copyrightMessage = "Qiao ";
$scope.copyrightYear = new Date();
};


The Question: How do I get Angular to recognise and use the partial template's controller?

Answer

While defining a controller, don't use any directory paths.

From the docs - https://docs.angularjs.org/api/ngRoute/provider/$routeProvider

controller – {(string|Function)=} – Controller fn that should be associated with newly created scope or the name of a registered controller if passed as a string.

Note that the registered controller never has the entire path, it is the function definition itself or the function's name (a string). You may need module names, if you have exported like that, but that's different from a directory path.

All you need is just use tags in index.html, which will include all your functions. Now if your functions are just plain javascript, and you don't intend using angular.module('app').controller there, use it in the app.js, Just angular.module('app').controller('anonHomeController', anonHomeController); Note that your definition can still remain in the Javascript file /some/path/totemplate/anonHomeController.js. I suggest you try that and see if it works.

app.js

    app.config(function ($routeProvider, $locationProvider) {
      $routeProvider
        .when("/", {
        templateUrl: 'templates/main/main.html',
        controller: 'MainCtrl'
      })

index.html

<script src="controllers.js"></script>

controllers.js

function MainCtrl ($scope) {
  $scope.name = 'World';

}

A working plnkr here