Dave Gordon
Dave Gordon

Reputation: 1835

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?

Upvotes: 2

Views: 3845

Answers (3)

Mahesh
Mahesh

Reputation: 1099

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 <script> 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

Upvotes: 1

aliasav
aliasav

Reputation: 3168

You don't need to add complete path in your app.js for defining controllers.

If you're controllers are defined in the same file, then this should do the job:

$routeProvider
        .when("/", {
            templateUrl: 'templates/anonHome/anonHome.html',
            controller: 'xyzController'
        });

app.controller("xyzController", function ($scope) {
 // controller function here
});

If you want your controllers to be in an external file, you'll have to do the following:

1. Define the controllers module: 

    angular.module('app.controllers', [])
    .controller("homeController", function(){....})

Name this file as controllers.js

2. Now your main app.js should include this:

    angular.module('app', [
            'app.controllers',
        ])
  1. Include controllers.js in your main html file

Upvotes: 1

sisyphus
sisyphus

Reputation: 462

You have created your controller for each view as a regular JS function, which is incorrect. It should be like

app.controller("anonHomeController", function ($scope) {
    $scope.Title = " Welcome to Qiao";
    // rest of the controller code 
});

and the file should be anonHomeController.js at the path you have defined in the config. you also do not need to include the scipt tag in the header of the view. Check for some example here

Upvotes: 1

Related Questions