I have all of my AngularJS controllers in one file, controllers.js. This file is structured as follows:
angular.module('myApp.controllers', [])
.controller('Ctrl1', ['$scope', '$http', function($scope, $http) {
}])
.controller('Ctrl2', ['$scope', '$http', function($scope, $http) }
}])
What I'd like to do is put Ctrl1 and Ctrl2 into separate files. I would then include both files in my index.html, but how should that be structured? I tried doing some thing like this and it throws an error in the web browser console saying it can't find my controllers. Any hints?
I searched StackOverflow and found this similar question - however, this syntax is using a different framework (CoffeeScript) on top of Angular, and so I haven't been able to follow.
File one:
angular.module('myApp.controllers', []);
File two:
angular.module('myApp.controllers').controller('Ctrl1', ['$scope', '$http', function($scope, $http){
}]);
File three:
angular.module('myApp.controllers').controller('Ctrl2', ['$scope', '$http', function($scope, $http){
}]);
Include in that order. I recommend 3 files so the module declaration is on its own.
As for folder structure there are many many many opinions on the subject, but these two are pretty good
Using the angular.module API with an array at the end will tell angular to create a new module:
myApp.js
// It is like saying "create a new module"
angular.module('myApp.controllers', []); // Notice the empty array at the end here
Using it without the array is actually a getter function. So to seperate your controllers, you can do:
Ctrl1.js
// It is just like saying "get this module and create a controller"
angular.module('myApp.controllers').controller('Ctrlr1', ['$scope', '$http', function($scope, $http) {}]);
Ctrl2.js
angular.module('myApp.controllers').controller('Ctrlr2', ['$scope', '$http', function($scope, $http) {}]);
During your javascript imports, just make sure myApp.js is after AngularJS but before any controllers / services / etc...otherwise angular won't be able to initialize your controllers.
Although both answers are technically correct, I want to introduce a different syntax choice for this answer. This imho makes it easier to read what's going on with injection, differentiate between etc.
File One
// Create the module that deals with controllers
angular.module('myApp.controllers', []);
File Two
// Here we get the module we created in file one
angular.module('myApp.controllers')
// We are adding a function called Ctrl1
// to the module we got in the line above
.controller('Ctrl1', Ctrl1);
// Inject my dependencies
Ctrl1.$inject = ['$scope', '$http'];
// Now create our controller function with all necessary logic
function Ctrl1($scope, $http) {
// Logic here
}
File Three
// Here we get the module we created in file one
angular.module('myApp.controllers')
// We are adding a function called Ctrl2
// to the module we got in the line above
.controller('Ctrl2', Ctrl2);
// Inject my dependencies
Ctrl2.$inject = ['$scope', '$http'];
// Now create our controller function with all necessary logic
function Ctrl2($scope, $http) {
// Logic here
}
What about this solution? Modules and Controllers in Files (at the end of the page) It works with multiple controllers, directives and so on:
app.js
var app = angular.module("myApp", ['deps']);
myCtrl.js
app.controller("myCtrl", function($scope) { ..});
html
<script src="app.js"></script>
<script src="myCtrl.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
Google has also a Best Practice Recommendations for Angular App Structure I really like to group by context. Not all the html in one folder, but for example all files for login (html, css, app.js,controller.js and so on). So if I work on a module, all the directives are easier to find.
For brevity, here's an ES2015 sample that doesn't rely on global variables
// controllers/example-controller.js
export const ExampleControllerName = "ExampleController"
export const ExampleController = ($scope) => {
// something...
}
// controllers/another-controller.js
export const AnotherControllerName = "AnotherController"
export const AnotherController = ($scope) => {
// functionality...
}
// app.js
import angular from "angular";
import {
ExampleControllerName,
ExampleController
} = "./controllers/example-controller";
import {
AnotherControllerName,
AnotherController
} = "./controllers/another-controller";
angular.module("myApp", [/* deps */])
.controller(ExampleControllerName, ExampleController)
.controller(AnotherControllerName, AnotherController)
Not so graceful, but the very much simple in implementation solution - using global variable.
In the "first" file:
window.myApp = angular.module("myApp", [])
....
in the "second" , "third", etc:
myApp.controller('MyController', function($scope) {
....
});
©2020 All rights reserved.