m0meni
m0meni

Reputation: 16445

Defining a controller in a $routeProvider route that is located in a separate file

The original code is as follows:

(function() {
    angular.module('test', ['ngRoute'])
        .config(function($routeProvider) {
            $routeProvider
                .when('/test', {
                    templateUrl: '/templates/test.html',
                    controller: 'testCtrl'
                })
                .when('/test2', {
                    templateUrl: '/templates/test2.html',
                    controller: 'test2Ctrl'
                })
                .otherwise({
                    redirectTo: '/test'
                });
        });
})();

//ANOTHER FILE
(function() {
    angular.module('test')
        .controller('testCtrl', function($scope) {
            $scope.name = "test";
        })
        .controller('test2Ctrl', function($scope) {
            $scope.name = "test2";
        });
});

There were no errors, but all that would show up in the templates was {{name}} instead of what was defined in the scope.

Then I tried moving the controllers into another module and dependency injected it in. Interestingly, even if the controllers were moved to a separate module it would not work:

(function () {
    angular.module('test2', []);
    angular.module('test', ['ngRoute', 'test2']);
})();

//ANOTHER FILE
(function() {
    angular.module('test')
        .config(function($routeProvider) {
            $routeProvider
                .when('/test', {
                    templateUrl: '/templates/test.html',
                    controller: 'testCtrl'
                })
                .when('/test2', {
                    templateUrl: '/templates/test2.html',
                    controller: 'test2Ctrl'
                })
                .otherwise({
                    redirectTo: '/test'
                });
        });
})();

//ANOTHER FILE
(function() {
    angular.module('test2')
        .controller('testCtrl', function($scope) {
            $scope.name = "test";
        })
        .controller('test2Ctrl', function($scope) {
            $scope.name = "test2";
        });
});

In fact, in this one it threw an error that the controllers could not be found.

From my understanding this is happening because due to the nature of how the config block runs, and how it runs before the controllers have been registered.

One way I've solved this is by instead moving the controller and template into a directive and then using the directive itself as the template.

(function() {
    angular.module('test')
        .config(function($routeProvider) {
            $routeProvider
                $routeProvider
                .when('/', {
                    template: '<test></test>'
                })
                .when('/test2', {
                    template: '<test2></test2>'
                })
                .when('/test3', {
                    template: '<test3></test3>'
                })
                .otherwise({
                    redirectTo: '/'
                });
        });
})();

I was wondering if anyone else had a way to support putting controllers into a router when your controllers are in a separate file.

Upvotes: 1

Views: 503

Answers (3)

Pankaj Parkar
Pankaj Parkar

Reputation: 136164

You have been missing an () self executing function (IIFE) on the file of your controller.

//ANOTHER FILE
(function() {
    angular.module('test2')
        .controller('testCtrl', function($scope) {
            $scope.name = "test";
        })
        .controller('test2Ctrl', function($scope) {
            $scope.name = "test2";
        });
})(); //<-- added here

Upvotes: 1

m0meni
m0meni

Reputation: 16445

This code here was missing the () that would execute it...

(function() {
    angular.module('test')
        .controller('testCtrl', function($scope) {
            $scope.name = "test";
        })
        .controller('test2Ctrl', function($scope) {
            $scope.name = "test2";
        });
});

Should be:

(function() {
    angular.module('test')
        .controller('testCtrl', function($scope) {
            $scope.name = "test";
        })
        .controller('test2Ctrl', function($scope) {
            $scope.name = "test2";
        });
})();

Upvotes: 1

Jorge Casariego
Jorge Casariego

Reputation: 22212

You can organize the project in this way

templates/
    test.html
    test2.html
app/
    app.js
    controllers/
        testCtrl.js
        test2Ctrl.js

app.js

(function() {
    angular.module('test', ['ngRoute'])
        .config(function($routeProvider) {
            $routeProvider
                .when('/test', {
                    templateUrl: '/templates/test.html',
                    controller: 'testCtrl'
                })
                .when('/test2', {
                    templateUrl: '/templates/test2.html',
                    controller: 'test2Ctrl'
                })
                .otherwise({
                    redirectTo: '/test'
                });
        });
})();

html files

Once you add the controllers in your html file may no longer have the problem

<html ng-app='myApp'>
    <body ng-controller='TextController'>
    ....
    ....
    ....
    <script src="app/controllers/testCtrl.js"></script>
    <script src="app/controllers/test2Ctrl.js"></script>
    </body>
</html>

Upvotes: 1

Related Questions